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 -------------------------------------------------------------------------*/
30 set *operKeyReset = NULL;
31 ast *staticAutos = NULL;
34 #define LRVAL(x) x->left->rvalue
35 #define RRVAL(x) x->right->rvalue
36 #define TRVAL(x) x->rvalue
37 #define LLVAL(x) x->left->lvalue
38 #define RLVAL(x) x->right->lvalue
39 #define TLVAL(x) x->lvalue
40 #define RTYPE(x) x->right->ftype
41 #define RETYPE(x) x->right->etype
42 #define LTYPE(x) x->left->ftype
43 #define LETYPE(x) x->left->etype
44 #define TTYPE(x) x->ftype
45 #define TETYPE(x) x->etype
53 ast *createIval (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
74 newAst (int type, void *op)
77 static int oldLineno = 0;
79 Safe_calloc (1, ex, sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : yylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
88 /* depending on the type */
92 ex->opval.val = (value *) op;
95 ex->opval.op = (long) op;
98 ex->opval.lnk = (sym_link *) op;
101 ex->opval.stmnt = (unsigned) op;
109 newAst_ (unsigned type)
112 static int oldLineno = 0;
114 ex = Safe_calloc (1, sizeof (ast));
117 ex->lineno = (noLineno ? oldLineno : yylineno);
118 ex->filename = currFname;
119 ex->level = NestLevel;
120 ex->block = currBlockno;
121 ex->initMode = inInitMode;
126 newAst_VALUE (value * val)
128 ast *ex = newAst_ (EX_VALUE);
134 newAst_OP (unsigned op)
136 ast *ex = newAst_ (EX_OP);
142 newAst_LINK (sym_link * val)
144 ast *ex = newAst_ (EX_LINK);
150 newAst_STMNT (unsigned val)
152 ast *ex = newAst_ (EX_STMNT);
153 ex->opval.stmnt = val;
157 /*-----------------------------------------------------------------*/
158 /* newNode - creates a new node */
159 /*-----------------------------------------------------------------*/
161 newNode (long op, ast * left, ast * right)
172 /*-----------------------------------------------------------------*/
173 /* newIfxNode - creates a new Ifx Node */
174 /*-----------------------------------------------------------------*/
176 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
180 /* if this is a literal then we already know the result */
181 if (condAst->etype && IS_LITERAL (condAst->etype))
183 /* then depending on the expression value */
184 if (floatFromVal (condAst->opval.val))
185 ifxNode = newNode (GOTO,
186 newAst_VALUE (symbolVal (trueLabel)),
189 ifxNode = newNode (GOTO,
190 newAst_VALUE (symbolVal (falseLabel)),
195 ifxNode = newNode (IFX, condAst, NULL);
196 ifxNode->trueLabel = trueLabel;
197 ifxNode->falseLabel = falseLabel;
203 /*-----------------------------------------------------------------*/
204 /* copyAstValues - copies value portion of ast if needed */
205 /*-----------------------------------------------------------------*/
207 copyAstValues (ast * dest, ast * src)
209 switch (src->opval.op)
212 dest->values.sym = copySymbolChain (src->values.sym);
216 dest->values.switchVals.swVals =
217 copyValue (src->values.switchVals.swVals);
218 dest->values.switchVals.swDefault =
219 src->values.switchVals.swDefault;
220 dest->values.switchVals.swNum =
221 src->values.switchVals.swNum;
225 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
226 strcpy (dest->values.inlineasm, src->values.inlineasm);
230 dest->values.constlist = copyLiteralList(src->values.constlist);
234 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
235 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
236 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
237 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
238 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
239 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
240 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
245 /*-----------------------------------------------------------------*/
246 /* copyAst - makes a copy of a given astession */
247 /*-----------------------------------------------------------------*/
256 dest = Safe_calloc (1, sizeof (ast));
258 dest->type = src->type;
259 dest->lineno = src->lineno;
260 dest->level = src->level;
261 dest->funcName = src->funcName;
262 dest->argSym = src->argSym;
264 /* if this is a leaf */
266 if (src->type == EX_VALUE)
268 dest->opval.val = copyValue (src->opval.val);
273 if (src->type == EX_LINK)
275 dest->opval.lnk = copyLinkChain (src->opval.lnk);
279 dest->opval.op = src->opval.op;
281 /* if this is a node that has special values */
282 copyAstValues (dest, src);
285 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
287 dest->trueLabel = copySymbol (src->trueLabel);
288 dest->falseLabel = copySymbol (src->falseLabel);
289 dest->left = copyAst (src->left);
290 dest->right = copyAst (src->right);
296 /*-----------------------------------------------------------------*/
297 /* hasSEFcalls - returns TRUE if tree has a function call */
298 /*-----------------------------------------------------------------*/
300 hasSEFcalls (ast * tree)
305 if (tree->type == EX_OP &&
306 (tree->opval.op == CALL ||
307 tree->opval.op == PCALL ||
308 tree->opval.op == '=' ||
309 tree->opval.op == INC_OP ||
310 tree->opval.op == DEC_OP))
313 return (hasSEFcalls (tree->left) |
314 hasSEFcalls (tree->right));
317 /*-----------------------------------------------------------------*/
318 /* isAstEqual - compares two asts & returns 1 if they are equal */
319 /*-----------------------------------------------------------------*/
321 isAstEqual (ast * t1, ast * t2)
330 if (t1->type != t2->type)
336 if (t1->opval.op != t2->opval.op)
338 return (isAstEqual (t1->left, t2->left) &&
339 isAstEqual (t1->right, t2->right));
343 if (t1->opval.val->sym)
345 if (!t2->opval.val->sym)
348 return isSymbolEqual (t1->opval.val->sym,
353 if (t2->opval.val->sym)
356 return (floatFromVal (t1->opval.val) ==
357 floatFromVal (t2->opval.val));
361 /* only compare these two types */
369 /*-----------------------------------------------------------------*/
370 /* resolveSymbols - resolve symbols from the symbol table */
371 /*-----------------------------------------------------------------*/
373 resolveSymbols (ast * tree)
375 /* walk the entire tree and check for values */
376 /* with symbols if we find one then replace */
377 /* symbol with that from the symbol table */
383 /* if not block & function */
384 if (tree->type == EX_OP &&
385 (tree->opval.op != FUNCTION &&
386 tree->opval.op != BLOCK &&
387 tree->opval.op != NULLOP))
389 filename = tree->filename;
390 lineno = tree->lineno;
393 /* make sure we resolve the true & false labels for ifx */
394 if (tree->type == EX_OP && tree->opval.op == IFX)
400 if ((csym = findSym (LabelTab, tree->trueLabel,
401 tree->trueLabel->name)))
402 tree->trueLabel = csym;
404 werror (E_LABEL_UNDEF, tree->trueLabel->name);
407 if (tree->falseLabel)
409 if ((csym = findSym (LabelTab,
411 tree->falseLabel->name)))
412 tree->falseLabel = csym;
414 werror (E_LABEL_UNDEF, tree->falseLabel->name);
419 /* if this is a label resolve it from the labelTab */
420 if (IS_AST_VALUE (tree) &&
421 tree->opval.val->sym &&
422 tree->opval.val->sym->islbl)
425 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
426 tree->opval.val->sym->name);
429 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
431 tree->opval.val->sym = csym;
433 goto resolveChildren;
436 /* do only for leafs */
437 if (IS_AST_VALUE (tree) &&
438 tree->opval.val->sym &&
439 !tree->opval.val->sym->implicit)
442 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
444 /* if found in the symbol table & they r not the same */
445 if (csym && tree->opval.val->sym != csym)
447 tree->opval.val->sym = csym;
448 tree->opval.val->type = csym->type;
449 tree->opval.val->etype = csym->etype;
452 /* if not found in the symbol table */
453 /* mark it as undefined assume it is */
454 /* an integer in data space */
455 if (!csym && !tree->opval.val->sym->implicit)
458 /* if this is a function name then */
459 /* mark it as returning an int */
462 tree->opval.val->sym->type = newLink ();
463 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
464 tree->opval.val->sym->type->next =
465 tree->opval.val->sym->etype = newIntLink ();
466 tree->opval.val->etype = tree->opval.val->etype;
467 tree->opval.val->type = tree->opval.val->sym->type;
468 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
469 allocVariables (tree->opval.val->sym);
473 tree->opval.val->sym->undefined = 1;
474 tree->opval.val->type =
475 tree->opval.val->etype = newIntLink ();
476 tree->opval.val->sym->type =
477 tree->opval.val->sym->etype = newIntLink ();
483 resolveSymbols (tree->left);
484 resolveSymbols (tree->right);
489 /*-----------------------------------------------------------------*/
490 /* setAstLineno - walks a ast tree & sets the line number */
491 /*-----------------------------------------------------------------*/
493 setAstLineno (ast * tree, int lineno)
498 tree->lineno = lineno;
499 setAstLineno (tree->left, lineno);
500 setAstLineno (tree->right, lineno);
505 /* this functions seems to be superfluous?! kmh */
507 /*-----------------------------------------------------------------*/
508 /* resolveFromTable - will return the symbal table value */
509 /*-----------------------------------------------------------------*/
511 resolveFromTable (value * val)
518 csym = findSymWithLevel (SymbolTab, val->sym);
520 /* if found in the symbol table & they r not the same */
521 if (csym && val->sym != csym &&
522 csym->level == val->sym->level &&
528 val->type = csym->type;
529 val->etype = csym->etype;
536 /*-----------------------------------------------------------------*/
537 /* funcOfType :- function of type with name */
538 /*-----------------------------------------------------------------*/
540 funcOfType (char *name, sym_link * type, sym_link * argType,
544 /* create the symbol */
545 sym = newSymbol (name, 0);
547 /* if arguments required */
552 args = sym->args = newValue ();
556 args->type = copyLinkChain (argType);
557 args->etype = getSpec (args->type);
560 args = args->next = newValue ();
564 /* setup return value */
565 sym->type = newLink ();
566 DCL_TYPE (sym->type) = FUNCTION;
567 sym->type->next = copyLinkChain (type);
568 sym->etype = getSpec (sym->type);
569 SPEC_RENT (sym->etype) = rent;
574 allocVariables (sym);
579 /*-----------------------------------------------------------------*/
580 /* reverseParms - will reverse a parameter tree */
581 /*-----------------------------------------------------------------*/
583 reverseParms (ast * ptree)
589 /* top down if we find a nonParm tree then quit */
590 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
593 ptree->left = ptree->right;
594 ptree->right = ttree;
595 reverseParms (ptree->left);
596 reverseParms (ptree->right);
602 /*-----------------------------------------------------------------*/
603 /* processParms - makes sure the parameters are okay and do some */
604 /* processing with them */
605 /*-----------------------------------------------------------------*/
607 processParms (ast * func,
614 sym_link *fetype = func->etype;
616 /* if none of them exist */
617 if (!defParm && !actParm)
621 if (getenv("DEBUG_SANITY")) {
622 fprintf (stderr, "addSym: %s ", defParm->name);
624 /* make sure the type is complete and sane */
625 checkTypeSanity(defParm->etype, defParm->name);
628 /* if the function is being called via a pointer & */
629 /* it has not been defined a reentrant then we cannot */
630 /* have parameters */
631 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
633 werror (W_NONRENT_ARGS);
637 /* if defined parameters ended but actual parameters */
638 /* exist and this is not defined as a variable arg */
639 /* also check if statckAuto option is specified */
640 if ((!defParm) && actParm && (!func->hasVargs) &&
641 !options.stackAuto && !IS_RENT (fetype))
643 werror (E_TOO_MANY_PARMS);
647 /* if defined parameters present but no actual parameters */
648 if (defParm && !actParm)
650 werror (E_TOO_FEW_PARMS);
654 /* If this is a varargs function... */
655 if (!defParm && actParm && func->hasVargs)
660 if (IS_CAST_OP (actParm)
661 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
663 /* Parameter was explicitly typecast; don't touch it. */
667 /* The ternary ('?') operator is weird: the ftype of the
668 * operator is the type of the condition, but it will return a
669 * (possibly) different type.
671 if (IS_TERNARY_OP(actParm))
673 assert(IS_COLON_OP(actParm->right));
674 assert(actParm->right->left);
675 ftype = actParm->right->left->ftype;
679 ftype = actParm->ftype;
682 /* If it's a small integer, upcast to int. */
683 if (IS_INTEGRAL (ftype)
684 && (getSize (ftype) < (unsigned) INTSIZE))
686 newType = newAst_LINK(INTTYPE);
689 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
691 newType = newAst_LINK (copyLinkChain(ftype));
692 DCL_TYPE (newType->opval.lnk) = GPOINTER;
695 if (IS_AGGREGATE (ftype))
697 newType = newAst_LINK (copyLinkChain (ftype));
698 DCL_TYPE (newType->opval.lnk) = GPOINTER;
702 /* cast required; change this op to a cast. */
703 ast *parmCopy = resolveSymbols (copyAst (actParm));
705 actParm->type = EX_OP;
706 actParm->opval.op = CAST;
707 actParm->left = newType;
708 actParm->right = parmCopy;
709 decorateType (actParm);
711 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
713 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
714 processParms (func, NULL, actParm->right, parmNumber, rightmost));
719 /* if defined parameters ended but actual has not & */
721 if (!defParm && actParm &&
722 (options.stackAuto || IS_RENT (fetype)))
725 resolveSymbols (actParm);
726 /* if this is a PARAM node then match left & right */
727 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
729 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
730 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
734 /* If we have found a value node by following only right-hand links,
735 * then we know that there are no more values after us.
737 * Therefore, if there are more defined parameters, the caller didn't
740 if (rightmost && defParm->next)
742 werror (E_TOO_FEW_PARMS);
747 /* the parameter type must be at least castable */
748 if (compareType (defParm->type, actParm->ftype) == 0)
753 if (!IS_SPEC(defParm->type) && !IS_SPEC(actParm->ftype)) {
754 // now we have two pointers, check if they point to the same
755 sym_link *dtype=defParm->type->next, *atype=actParm->ftype->next;
758 (dtype->next && !atype->next) ||
759 (!dtype->next && atype->next) ||
760 compareType (dtype, atype)!=1) {
763 } while (dtype->next && atype->next);
764 if (IS_SPEC(dtype) && IS_SPEC(atype)) {
765 // ok so far, we have two etypes, they must have the same SCLASS
766 if (SPEC_SCLS(dtype)!=SPEC_SCLS(atype)) {
772 werror (W_INCOMPAT_CAST);
773 fprintf (stderr, "type --> '");
774 printTypeChain (actParm->ftype, stderr);
775 fprintf (stderr, "' ");
776 fprintf (stderr, "assigned to type --> '");
777 printTypeChain (defParm->type, stderr);
778 fprintf (stderr, "'\n");
783 /* if the parameter is castable then add the cast */
784 if (compareType (defParm->type, actParm->ftype) < 0)
786 ast *pTree = resolveSymbols (copyAst (actParm));
788 /* now change the current one to a cast */
789 actParm->type = EX_OP;
790 actParm->opval.op = CAST;
791 actParm->left = newAst_LINK (defParm->type);
792 actParm->right = pTree;
793 actParm->etype = defParm->etype;
794 actParm->ftype = defParm->type;
797 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
799 actParm->argSym = defParm->sym;
800 /* make a copy and change the regparm type to the defined parm */
801 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
802 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
806 /*-----------------------------------------------------------------*/
807 /* createIvalType - generates ival for basic types */
808 /*-----------------------------------------------------------------*/
810 createIvalType (ast * sym, sym_link * type, initList * ilist)
814 /* if initList is deep */
815 if (ilist->type == INIT_DEEP)
816 ilist = ilist->init.deep;
818 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
819 return decorateType (newNode ('=', sym, iExpr));
822 /*-----------------------------------------------------------------*/
823 /* createIvalStruct - generates initial value for structures */
824 /*-----------------------------------------------------------------*/
826 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
832 sflds = SPEC_STRUCT (type)->fields;
833 if (ilist->type != INIT_DEEP)
835 werror (E_INIT_STRUCT, "");
839 iloop = ilist->init.deep;
841 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
845 /* if we have come to end */
849 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
850 lAst = decorateType (resolveSymbols (lAst));
851 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
857 /*-----------------------------------------------------------------*/
858 /* createIvalArray - generates code for array initialization */
859 /*-----------------------------------------------------------------*/
861 createIvalArray (ast * sym, sym_link * type, initList * ilist)
865 int lcnt = 0, size = 0;
866 literalList *literalL;
868 /* take care of the special case */
869 /* array of characters can be init */
871 if (IS_CHAR (type->next))
872 if ((rast = createIvalCharPtr (sym,
874 decorateType (resolveSymbols (list2expr (ilist))))))
876 return decorateType (resolveSymbols (rast));
878 /* not the special case */
879 if (ilist->type != INIT_DEEP)
881 werror (E_INIT_STRUCT, "");
885 iloop = ilist->init.deep;
886 lcnt = DCL_ELEM (type);
888 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
892 aSym = decorateType (resolveSymbols(sym));
894 rast = newNode(ARRAYINIT, aSym, NULL);
895 rast->values.constlist = literalL;
897 // Make sure size is set to length of initializer list.
904 if (lcnt && size > lcnt)
906 // Array size was specified, and we have more initializers than needed.
907 char *name=sym->opval.val->sym->name;
908 int lineno=sym->opval.val->sym->lineDef;
910 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
919 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
920 aSym = decorateType (resolveSymbols (aSym));
921 rast = createIval (aSym, type->next, iloop, rast);
922 iloop = (iloop ? iloop->next : NULL);
928 /* no of elements given and we */
929 /* have generated for all of them */
932 // there has to be a better way
933 char *name=sym->opval.val->sym->name;
934 int lineno=sym->opval.val->sym->lineDef;
935 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
942 /* if we have not been given a size */
943 if (!DCL_ELEM (type))
945 DCL_ELEM (type) = size;
948 return decorateType (resolveSymbols (rast));
952 /*-----------------------------------------------------------------*/
953 /* createIvalCharPtr - generates initial values for char pointers */
954 /*-----------------------------------------------------------------*/
956 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
960 /* if this is a pointer & right is a literal array then */
961 /* just assignment will do */
962 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
963 SPEC_SCLS (iexpr->etype) == S_CODE)
964 && IS_ARRAY (iexpr->ftype)))
965 return newNode ('=', sym, iexpr);
967 /* left side is an array so we have to assign each */
969 if ((IS_LITERAL (iexpr->etype) ||
970 SPEC_SCLS (iexpr->etype) == S_CODE)
971 && IS_ARRAY (iexpr->ftype))
973 /* for each character generate an assignment */
974 /* to the array element */
975 char *s = SPEC_CVAL (iexpr->etype).v_char;
980 rast = newNode (NULLOP,
984 newAst_VALUE (valueFromLit ((float) i))),
985 newAst_VALUE (valueFromLit (*s))));
989 rast = newNode (NULLOP,
993 newAst_VALUE (valueFromLit ((float) i))),
994 newAst_VALUE (valueFromLit (*s))));
995 return decorateType (resolveSymbols (rast));
1001 /*-----------------------------------------------------------------*/
1002 /* createIvalPtr - generates initial value for pointers */
1003 /*-----------------------------------------------------------------*/
1005 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1011 if (ilist->type == INIT_DEEP)
1012 ilist = ilist->init.deep;
1014 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1016 /* if character pointer */
1017 if (IS_CHAR (type->next))
1018 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1021 return newNode ('=', sym, iexpr);
1024 /*-----------------------------------------------------------------*/
1025 /* createIval - generates code for initial value */
1026 /*-----------------------------------------------------------------*/
1028 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1035 /* if structure then */
1036 if (IS_STRUCT (type))
1037 rast = createIvalStruct (sym, type, ilist);
1039 /* if this is a pointer */
1041 rast = createIvalPtr (sym, type, ilist);
1043 /* if this is an array */
1044 if (IS_ARRAY (type))
1045 rast = createIvalArray (sym, type, ilist);
1047 /* if type is SPECIFIER */
1049 rast = createIvalType (sym, type, ilist);
1052 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1054 return decorateType (resolveSymbols (rast));
1057 /*-----------------------------------------------------------------*/
1058 /* initAggregates - initialises aggregate variables with initv */
1059 /*-----------------------------------------------------------------*/
1061 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1063 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1067 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1069 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1070 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1071 "with -mmcs51 and --model-large");
1075 if (SPEC_OCLS(sym->etype)==xdata &&
1076 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1079 newSym=copySymbol (sym);
1080 SPEC_OCLS(newSym->etype)=code;
1081 sprintf (newSym->name, "%s_init__", sym->name);
1082 sprintf (newSym->rname,"%s_init__", sym->rname);
1083 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1085 // emit it in the static segment
1086 addSet(&statsg->syms, newSym);
1088 // now memcpy() the entire array from cseg
1089 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1090 newAst_VALUE (symbolVal (sym)),
1091 newAst_VALUE (symbolVal (newSym)));
1092 return decorateType(resolveSymbols(ast));
1096 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1099 /*-----------------------------------------------------------------*/
1100 /* gatherAutoInit - creates assignment expressions for initial */
1102 /*-----------------------------------------------------------------*/
1104 gatherAutoInit (symbol * autoChain)
1111 for (sym = autoChain; sym; sym = sym->next)
1114 /* resolve the symbols in the ival */
1116 resolveIvalSym (sym->ival);
1118 /* if this is a static variable & has an */
1119 /* initial value the code needs to be lifted */
1120 /* here to the main portion since they can be */
1121 /* initialised only once at the start */
1122 if (IS_STATIC (sym->etype) && sym->ival &&
1123 SPEC_SCLS (sym->etype) != S_CODE)
1127 // this can only be a constant
1128 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1129 werror (E_CONST_EXPECTED);
1132 /* insert the symbol into the symbol table */
1133 /* with level = 0 & name = rname */
1134 newSym = copySymbol (sym);
1135 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1137 /* now lift the code to main */
1138 if (IS_AGGREGATE (sym->type))
1139 work = initAggregates (sym, sym->ival, NULL);
1141 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1142 list2expr (sym->ival));
1144 setAstLineno (work, sym->lineDef);
1148 staticAutos = newNode (NULLOP, staticAutos, work);
1155 /* if there is an initial value */
1156 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1158 if (IS_AGGREGATE (sym->type))
1159 work = initAggregates (sym, sym->ival, NULL);
1161 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1162 list2expr (sym->ival));
1164 setAstLineno (work, sym->lineDef);
1167 init = newNode (NULLOP, init, work);
1176 /*-----------------------------------------------------------------*/
1177 /* stringToSymbol - creates a symbol from a literal string */
1178 /*-----------------------------------------------------------------*/
1180 stringToSymbol (value * val)
1182 char name[SDCC_NAME_MAX + 1];
1183 static int charLbl = 0;
1186 sprintf (name, "_str_%d", charLbl++);
1187 sym = newSymbol (name, 0); /* make it @ level 0 */
1188 strcpy (sym->rname, name);
1190 /* copy the type from the value passed */
1191 sym->type = copyLinkChain (val->type);
1192 sym->etype = getSpec (sym->type);
1193 /* change to storage class & output class */
1194 SPEC_SCLS (sym->etype) = S_CODE;
1195 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1196 SPEC_STAT (sym->etype) = 1;
1197 /* make the level & block = 0 */
1198 sym->block = sym->level = 0;
1200 /* create an ival */
1201 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1206 allocVariables (sym);
1209 return symbolVal (sym);
1213 /*-----------------------------------------------------------------*/
1214 /* processBlockVars - will go thru the ast looking for block if */
1215 /* a block is found then will allocate the syms */
1216 /* will also gather the auto inits present */
1217 /*-----------------------------------------------------------------*/
1219 processBlockVars (ast * tree, int *stack, int action)
1224 /* if this is a block */
1225 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1229 if (action == ALLOCATE)
1231 *stack += allocVariables (tree->values.sym);
1232 autoInit = gatherAutoInit (tree->values.sym);
1234 /* if there are auto inits then do them */
1236 tree->left = newNode (NULLOP, autoInit, tree->left);
1238 else /* action is deallocate */
1239 deallocLocal (tree->values.sym);
1242 processBlockVars (tree->left, stack, action);
1243 processBlockVars (tree->right, stack, action);
1247 /*-----------------------------------------------------------------*/
1248 /* constExprValue - returns the value of a constant expression */
1249 /*-----------------------------------------------------------------*/
1251 constExprValue (ast * cexpr, int check)
1253 cexpr = decorateType (resolveSymbols (cexpr));
1255 /* if this is not a constant then */
1256 if (!IS_LITERAL (cexpr->ftype))
1258 /* then check if this is a literal array
1260 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1261 SPEC_CVAL (cexpr->etype).v_char &&
1262 IS_ARRAY (cexpr->ftype))
1264 value *val = valFromType (cexpr->ftype);
1265 SPEC_SCLS (val->etype) = S_LITERAL;
1266 val->sym = cexpr->opval.val->sym;
1267 val->sym->type = copyLinkChain (cexpr->ftype);
1268 val->sym->etype = getSpec (val->sym->type);
1269 strcpy (val->name, cexpr->opval.val->sym->rname);
1273 /* if we are casting a literal value then */
1274 if (IS_AST_OP (cexpr) &&
1275 cexpr->opval.op == CAST &&
1276 IS_LITERAL (cexpr->left->ftype))
1277 return valCastLiteral (cexpr->ftype,
1278 floatFromVal (cexpr->left->opval.val));
1280 if (IS_AST_VALUE (cexpr))
1281 return cexpr->opval.val;
1284 werror (E_CONST_EXPECTED, "found expression");
1289 /* return the value */
1290 return cexpr->opval.val;
1294 /*-----------------------------------------------------------------*/
1295 /* isLabelInAst - will return true if a given label is found */
1296 /*-----------------------------------------------------------------*/
1298 isLabelInAst (symbol * label, ast * tree)
1300 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1303 if (IS_AST_OP (tree) &&
1304 tree->opval.op == LABEL &&
1305 isSymbolEqual (AST_SYMBOL (tree->left), label))
1308 return isLabelInAst (label, tree->right) &&
1309 isLabelInAst (label, tree->left);
1313 /*-----------------------------------------------------------------*/
1314 /* isLoopCountable - return true if the loop count can be determi- */
1315 /* -ned at compile time . */
1316 /*-----------------------------------------------------------------*/
1318 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1319 symbol ** sym, ast ** init, ast ** end)
1322 /* the loop is considered countable if the following
1323 conditions are true :-
1325 a) initExpr :- <sym> = <const>
1326 b) condExpr :- <sym> < <const1>
1327 c) loopExpr :- <sym> ++
1330 /* first check the initExpr */
1331 if (IS_AST_OP (initExpr) &&
1332 initExpr->opval.op == '=' && /* is assignment */
1333 IS_AST_SYM_VALUE (initExpr->left))
1334 { /* left is a symbol */
1336 *sym = AST_SYMBOL (initExpr->left);
1337 *init = initExpr->right;
1342 /* for now the symbol has to be of
1344 if (!IS_INTEGRAL ((*sym)->type))
1347 /* now check condExpr */
1348 if (IS_AST_OP (condExpr))
1351 switch (condExpr->opval.op)
1354 if (IS_AST_SYM_VALUE (condExpr->left) &&
1355 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1356 IS_AST_LIT_VALUE (condExpr->right))
1358 *end = condExpr->right;
1364 if (IS_AST_OP (condExpr->left) &&
1365 condExpr->left->opval.op == '>' &&
1366 IS_AST_LIT_VALUE (condExpr->left->right) &&
1367 IS_AST_SYM_VALUE (condExpr->left->left) &&
1368 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1371 *end = newNode ('+', condExpr->left->right,
1372 newAst_VALUE (constVal ("1")));
1383 /* check loop expression is of the form <sym>++ */
1384 if (!IS_AST_OP (loopExpr))
1387 /* check if <sym> ++ */
1388 if (loopExpr->opval.op == INC_OP)
1394 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1395 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1402 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1403 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1411 if (loopExpr->opval.op == ADD_ASSIGN)
1414 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1415 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1416 IS_AST_LIT_VALUE (loopExpr->right) &&
1417 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1425 /*-----------------------------------------------------------------*/
1426 /* astHasVolatile - returns true if ast contains any volatile */
1427 /*-----------------------------------------------------------------*/
1429 astHasVolatile (ast * tree)
1434 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1437 if (IS_AST_OP (tree))
1438 return astHasVolatile (tree->left) ||
1439 astHasVolatile (tree->right);
1444 /*-----------------------------------------------------------------*/
1445 /* astHasPointer - return true if the ast contains any ptr variable */
1446 /*-----------------------------------------------------------------*/
1448 astHasPointer (ast * tree)
1453 if (IS_AST_LINK (tree))
1456 /* if we hit an array expression then check
1457 only the left side */
1458 if (IS_AST_OP (tree) && tree->opval.op == '[')
1459 return astHasPointer (tree->left);
1461 if (IS_AST_VALUE (tree))
1462 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1464 return astHasPointer (tree->left) ||
1465 astHasPointer (tree->right);
1469 /*-----------------------------------------------------------------*/
1470 /* astHasSymbol - return true if the ast has the given symbol */
1471 /*-----------------------------------------------------------------*/
1473 astHasSymbol (ast * tree, symbol * sym)
1475 if (!tree || IS_AST_LINK (tree))
1478 if (IS_AST_VALUE (tree))
1480 if (IS_AST_SYM_VALUE (tree))
1481 return isSymbolEqual (AST_SYMBOL (tree), sym);
1486 return astHasSymbol (tree->left, sym) ||
1487 astHasSymbol (tree->right, sym);
1490 /*-----------------------------------------------------------------*/
1491 /* astHasDeref - return true if the ast has an indirect access */
1492 /*-----------------------------------------------------------------*/
1494 astHasDeref (ast * tree)
1496 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1499 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1501 return astHasDeref (tree->left) || astHasDeref (tree->right);
1504 /*-----------------------------------------------------------------*/
1505 /* isConformingBody - the loop body has to conform to a set of rules */
1506 /* for the loop to be considered reversible read on for rules */
1507 /*-----------------------------------------------------------------*/
1509 isConformingBody (ast * pbody, symbol * sym, ast * body)
1512 /* we are going to do a pre-order traversal of the
1513 tree && check for the following conditions. (essentially
1514 a set of very shallow tests )
1515 a) the sym passed does not participate in
1516 any arithmetic operation
1517 b) There are no function calls
1518 c) all jumps are within the body
1519 d) address of loop control variable not taken
1520 e) if an assignment has a pointer on the
1521 left hand side make sure right does not have
1522 loop control variable */
1524 /* if we reach the end or a leaf then true */
1525 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1529 /* if anything else is "volatile" */
1530 if (IS_VOLATILE (TETYPE (pbody)))
1533 /* we will walk the body in a pre-order traversal for
1535 switch (pbody->opval.op)
1537 /*------------------------------------------------------------------*/
1539 return isConformingBody (pbody->right, sym, body);
1541 /*------------------------------------------------------------------*/
1546 /*------------------------------------------------------------------*/
1547 case INC_OP: /* incerement operator unary so left only */
1550 /* sure we are not sym is not modified */
1552 IS_AST_SYM_VALUE (pbody->left) &&
1553 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1557 IS_AST_SYM_VALUE (pbody->right) &&
1558 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1563 /*------------------------------------------------------------------*/
1565 case '*': /* can be unary : if right is null then unary operation */
1570 /* if right is NULL then unary operation */
1571 /*------------------------------------------------------------------*/
1572 /*----------------------------*/
1574 /*----------------------------*/
1577 if (IS_AST_SYM_VALUE (pbody->left) &&
1578 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1581 return isConformingBody (pbody->left, sym, body);
1585 if (astHasSymbol (pbody->left, sym) ||
1586 astHasSymbol (pbody->right, sym))
1591 /*------------------------------------------------------------------*/
1599 if (IS_AST_SYM_VALUE (pbody->left) &&
1600 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1603 if (IS_AST_SYM_VALUE (pbody->right) &&
1604 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1607 return isConformingBody (pbody->left, sym, body) &&
1608 isConformingBody (pbody->right, sym, body);
1615 if (IS_AST_SYM_VALUE (pbody->left) &&
1616 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1618 return isConformingBody (pbody->left, sym, body);
1620 /*------------------------------------------------------------------*/
1632 case SIZEOF: /* evaluate wihout code generation */
1634 return isConformingBody (pbody->left, sym, body) &&
1635 isConformingBody (pbody->right, sym, body);
1637 /*------------------------------------------------------------------*/
1640 /* if left has a pointer & right has loop
1641 control variable then we cannot */
1642 if (astHasPointer (pbody->left) &&
1643 astHasSymbol (pbody->right, sym))
1645 if (astHasVolatile (pbody->left))
1648 if (IS_AST_SYM_VALUE (pbody->left) &&
1649 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1652 if (astHasVolatile (pbody->left))
1655 if (astHasDeref(pbody->right)) return FALSE;
1657 return isConformingBody (pbody->left, sym, body) &&
1658 isConformingBody (pbody->right, sym, body);
1669 assert ("Parser should not have generated this\n");
1671 /*------------------------------------------------------------------*/
1672 /*----------------------------*/
1673 /* comma operator */
1674 /*----------------------------*/
1676 return isConformingBody (pbody->left, sym, body) &&
1677 isConformingBody (pbody->right, sym, body);
1679 /*------------------------------------------------------------------*/
1680 /*----------------------------*/
1682 /*----------------------------*/
1686 /*------------------------------------------------------------------*/
1687 /*----------------------------*/
1688 /* return statement */
1689 /*----------------------------*/
1694 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1699 if (astHasSymbol (pbody->left, sym))
1706 return isConformingBody (pbody->left, sym, body) &&
1707 isConformingBody (pbody->right, sym, body);
1713 /*-----------------------------------------------------------------*/
1714 /* isLoopReversible - takes a for loop as input && returns true */
1715 /* if the for loop is reversible. If yes will set the value of */
1716 /* the loop control var & init value & termination value */
1717 /*-----------------------------------------------------------------*/
1719 isLoopReversible (ast * loop, symbol ** loopCntrl,
1720 ast ** init, ast ** end)
1722 /* if option says don't do it then don't */
1723 if (optimize.noLoopReverse)
1725 /* there are several tests to determine this */
1727 /* for loop has to be of the form
1728 for ( <sym> = <const1> ;
1729 [<sym> < <const2>] ;
1730 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1732 if (!isLoopCountable (AST_FOR (loop, initExpr),
1733 AST_FOR (loop, condExpr),
1734 AST_FOR (loop, loopExpr),
1735 loopCntrl, init, end))
1738 /* now do some serious checking on the body of the loop
1741 return isConformingBody (loop->left, *loopCntrl, loop->left);
1745 /*-----------------------------------------------------------------*/
1746 /* replLoopSym - replace the loop sym by loop sym -1 */
1747 /*-----------------------------------------------------------------*/
1749 replLoopSym (ast * body, symbol * sym)
1752 if (!body || IS_AST_LINK (body))
1755 if (IS_AST_SYM_VALUE (body))
1758 if (isSymbolEqual (AST_SYMBOL (body), sym))
1762 body->opval.op = '-';
1763 body->left = newAst_VALUE (symbolVal (sym));
1764 body->right = newAst_VALUE (constVal ("1"));
1772 replLoopSym (body->left, sym);
1773 replLoopSym (body->right, sym);
1777 /*-----------------------------------------------------------------*/
1778 /* reverseLoop - do the actual loop reversal */
1779 /*-----------------------------------------------------------------*/
1781 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1785 /* create the following tree
1790 if (sym) goto for_continue ;
1793 /* put it together piece by piece */
1794 rloop = newNode (NULLOP,
1795 createIf (newAst_VALUE (symbolVal (sym)),
1797 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1800 newAst_VALUE (symbolVal (sym)),
1803 replLoopSym (loop->left, sym);
1805 rloop = newNode (NULLOP,
1807 newAst_VALUE (symbolVal (sym)),
1808 newNode ('-', end, init)),
1809 createLabel (AST_FOR (loop, continueLabel),
1813 newNode (SUB_ASSIGN,
1814 newAst_VALUE (symbolVal (sym)),
1815 newAst_VALUE (constVal ("1"))),
1818 return decorateType (rloop);
1822 //#define DEMAND_INTEGER_PROMOTION
1824 #ifdef DEMAND_INTEGER_PROMOTION
1826 /*-----------------------------------------------------------------*/
1827 /* walk a tree looking for the leaves. Add a typecast to the given */
1828 /* type to each value leaf node. */
1829 /*-----------------------------------------------------------------*/
1831 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1833 if (!node || IS_CALLOP(node))
1835 /* WTF? We should never get here. */
1839 if (!node->left && !node->right)
1841 /* We're at a leaf; if it's a value, apply the typecast */
1842 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1844 *parentPtr = decorateType (newNode (CAST,
1845 newAst_LINK (copyLinkChain (type)),
1853 pushTypeCastToLeaves (type, node->left, &(node->left));
1857 pushTypeCastToLeaves (type, node->right, &(node->right));
1864 /*-----------------------------------------------------------------*/
1865 /* Given an assignment operation in a tree, determine if the LHS */
1866 /* (the result) has a different (integer) type than the RHS. */
1867 /* If so, walk the RHS and add a typecast to the type of the LHS */
1868 /* to all leaf nodes. */
1869 /*-----------------------------------------------------------------*/
1871 propAsgType (ast * tree)
1873 #ifdef DEMAND_INTEGER_PROMOTION
1874 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1876 /* Nothing to do here... */
1880 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1882 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1889 /*-----------------------------------------------------------------*/
1890 /* decorateType - compute type for this tree also does type cheking */
1891 /* this is done bottom up, since type have to flow upwards */
1892 /* it also does constant folding, and paramater checking */
1893 /*-----------------------------------------------------------------*/
1895 decorateType (ast * tree)
1903 /* if already has type then do nothing */
1904 if (tree->decorated)
1907 tree->decorated = 1;
1909 /* print the line */
1910 /* if not block & function */
1911 if (tree->type == EX_OP &&
1912 (tree->opval.op != FUNCTION &&
1913 tree->opval.op != BLOCK &&
1914 tree->opval.op != NULLOP))
1916 filename = tree->filename;
1917 lineno = tree->lineno;
1920 /* if any child is an error | this one is an error do nothing */
1921 if (tree->isError ||
1922 (tree->left && tree->left->isError) ||
1923 (tree->right && tree->right->isError))
1926 /*------------------------------------------------------------------*/
1927 /*----------------------------*/
1928 /* leaf has been reached */
1929 /*----------------------------*/
1930 /* if this is of type value */
1931 /* just get the type */
1932 if (tree->type == EX_VALUE)
1935 if (IS_LITERAL (tree->opval.val->etype))
1938 /* if this is a character array then declare it */
1939 if (IS_ARRAY (tree->opval.val->type))
1940 tree->opval.val = stringToSymbol (tree->opval.val);
1942 /* otherwise just copy the type information */
1943 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1944 if (funcInChain (tree->opval.val->type))
1946 tree->hasVargs = tree->opval.val->sym->hasVargs;
1947 tree->args = copyValueChain (tree->opval.val->sym->args);
1952 if (tree->opval.val->sym)
1954 /* if the undefined flag is set then give error message */
1955 if (tree->opval.val->sym->undefined)
1957 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1959 TTYPE (tree) = TETYPE (tree) =
1960 tree->opval.val->type = tree->opval.val->sym->type =
1961 tree->opval.val->etype = tree->opval.val->sym->etype =
1962 copyLinkChain (INTTYPE);
1967 /* if impilicit i.e. struct/union member then no type */
1968 if (tree->opval.val->sym->implicit)
1969 TTYPE (tree) = TETYPE (tree) = NULL;
1974 /* else copy the type */
1975 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1977 /* and mark it as referenced */
1978 tree->opval.val->sym->isref = 1;
1979 /* if this is of type function or function pointer */
1980 if (funcInChain (tree->opval.val->type))
1982 tree->hasVargs = tree->opval.val->sym->hasVargs;
1983 tree->args = copyValueChain (tree->opval.val->sym->args);
1993 /* if type link for the case of cast */
1994 if (tree->type == EX_LINK)
1996 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2003 dtl = decorateType (tree->left);
2004 dtr = decorateType (tree->right);
2006 /* this is to take care of situations
2007 when the tree gets rewritten */
2008 if (dtl != tree->left)
2010 if (dtr != tree->right)
2014 /* depending on type of operator do */
2016 switch (tree->opval.op)
2018 /*------------------------------------------------------------------*/
2019 /*----------------------------*/
2021 /*----------------------------*/
2024 /* determine which is the array & which the index */
2025 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2028 ast *tempTree = tree->left;
2029 tree->left = tree->right;
2030 tree->right = tempTree;
2033 /* first check if this is a array or a pointer */
2034 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2036 werror (E_NEED_ARRAY_PTR, "[]");
2037 goto errorTreeReturn;
2040 /* check if the type of the idx */
2041 if (!IS_INTEGRAL (RTYPE (tree)))
2043 werror (E_IDX_NOT_INT);
2044 goto errorTreeReturn;
2047 /* if the left is an rvalue then error */
2050 werror (E_LVALUE_REQUIRED, "array access");
2051 goto errorTreeReturn;
2054 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2055 if (IS_PTR(LTYPE(tree))) {
2056 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2060 /*------------------------------------------------------------------*/
2061 /*----------------------------*/
2063 /*----------------------------*/
2065 /* if this is not a structure */
2066 if (!IS_STRUCT (LTYPE (tree)))
2068 werror (E_STRUCT_UNION, ".");
2069 goto errorTreeReturn;
2071 TTYPE (tree) = structElemType (LTYPE (tree),
2072 (tree->right->type == EX_VALUE ?
2073 tree->right->opval.val : NULL), &tree->args);
2074 TETYPE (tree) = getSpec (TTYPE (tree));
2077 /*------------------------------------------------------------------*/
2078 /*----------------------------*/
2079 /* struct/union pointer */
2080 /*----------------------------*/
2082 /* if not pointer to a structure */
2083 if (!IS_PTR (LTYPE (tree)))
2085 werror (E_PTR_REQD);
2086 goto errorTreeReturn;
2089 if (!IS_STRUCT (LTYPE (tree)->next))
2091 werror (E_STRUCT_UNION, "->");
2092 goto errorTreeReturn;
2095 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2096 (tree->right->type == EX_VALUE ?
2097 tree->right->opval.val : NULL), &tree->args);
2098 TETYPE (tree) = getSpec (TTYPE (tree));
2101 /*------------------------------------------------------------------*/
2102 /*----------------------------*/
2103 /* ++/-- operation */
2104 /*----------------------------*/
2105 case INC_OP: /* incerement operator unary so left only */
2108 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2109 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2110 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
2111 werror (E_CODE_WRITE, "++/--");
2120 /*------------------------------------------------------------------*/
2121 /*----------------------------*/
2123 /*----------------------------*/
2124 case '&': /* can be unary */
2125 /* if right is NULL then unary operation */
2126 if (tree->right) /* not an unary operation */
2129 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2131 werror (E_BITWISE_OP);
2132 werror (W_CONTINUE, "left & right types are ");
2133 printTypeChain (LTYPE (tree), stderr);
2134 fprintf (stderr, ",");
2135 printTypeChain (RTYPE (tree), stderr);
2136 fprintf (stderr, "\n");
2137 goto errorTreeReturn;
2140 /* if they are both literal */
2141 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2143 tree->type = EX_VALUE;
2144 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2145 valFromType (RETYPE (tree)), '&');
2147 tree->right = tree->left = NULL;
2148 TETYPE (tree) = tree->opval.val->etype;
2149 TTYPE (tree) = tree->opval.val->type;
2153 /* see if this is a GETHBIT operation if yes
2156 ast *otree = optimizeGetHbit (tree);
2159 return decorateType (otree);
2163 // we can't do this because of "(int & 0xff) << 3"
2165 /* if right or left is literal then result of that type */
2166 if (IS_LITERAL (RTYPE (tree)))
2169 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2170 TETYPE (tree) = getSpec (TTYPE (tree));
2171 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2175 if (IS_LITERAL (LTYPE (tree)))
2177 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2178 TETYPE (tree) = getSpec (TTYPE (tree));
2179 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2185 computeType (LTYPE (tree), RTYPE (tree));
2186 TETYPE (tree) = getSpec (TTYPE (tree));
2191 computeType (LTYPE (tree), RTYPE (tree));
2192 TETYPE (tree) = getSpec (TTYPE (tree));
2194 LRVAL (tree) = RRVAL (tree) = 1;
2198 /*------------------------------------------------------------------*/
2199 /*----------------------------*/
2201 /*----------------------------*/
2203 p->class = DECLARATOR;
2204 /* if bit field then error */
2205 if (IS_BITVAR (tree->left->etype))
2207 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2208 goto errorTreeReturn;
2211 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2213 werror (E_ILLEGAL_ADDR, "address of register variable");
2214 goto errorTreeReturn;
2217 if (IS_FUNC (LTYPE (tree)))
2219 werror (E_ILLEGAL_ADDR, "address of function");
2220 goto errorTreeReturn;
2225 werror (E_LVALUE_REQUIRED, "address of");
2226 goto errorTreeReturn;
2228 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2230 DCL_TYPE (p) = CPOINTER;
2231 DCL_PTR_CONST (p) = port->mem.code_ro;
2233 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2234 DCL_TYPE (p) = FPOINTER;
2235 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2236 DCL_TYPE (p) = PPOINTER;
2237 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2238 DCL_TYPE (p) = IPOINTER;
2239 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2240 DCL_TYPE (p) = EEPPOINTER;
2242 DCL_TYPE (p) = POINTER;
2244 if (IS_AST_SYM_VALUE (tree->left))
2246 AST_SYMBOL (tree->left)->addrtaken = 1;
2247 AST_SYMBOL (tree->left)->allocreq = 1;
2250 p->next = LTYPE (tree);
2252 TETYPE (tree) = getSpec (TTYPE (tree));
2253 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2254 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2259 /*------------------------------------------------------------------*/
2260 /*----------------------------*/
2262 /*----------------------------*/
2264 /* if the rewrite succeeds then don't go any furthur */
2266 ast *wtree = optimizeRRCRLC (tree);
2268 return decorateType (wtree);
2270 /*------------------------------------------------------------------*/
2271 /*----------------------------*/
2273 /*----------------------------*/
2275 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2277 werror (E_BITWISE_OP);
2278 werror (W_CONTINUE, "left & right types are ");
2279 printTypeChain (LTYPE (tree), stderr);
2280 fprintf (stderr, ",");
2281 printTypeChain (RTYPE (tree), stderr);
2282 fprintf (stderr, "\n");
2283 goto errorTreeReturn;
2286 /* if they are both literal then */
2287 /* rewrite the tree */
2288 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2290 tree->type = EX_VALUE;
2291 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2292 valFromType (RETYPE (tree)),
2294 tree->right = tree->left = NULL;
2295 TETYPE (tree) = tree->opval.val->etype;
2296 TTYPE (tree) = tree->opval.val->type;
2299 LRVAL (tree) = RRVAL (tree) = 1;
2300 TETYPE (tree) = getSpec (TTYPE (tree) =
2301 computeType (LTYPE (tree),
2304 /*------------------------------------------------------------------*/
2305 /*----------------------------*/
2307 /*----------------------------*/
2309 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2311 werror (E_INVALID_OP, "divide");
2312 goto errorTreeReturn;
2314 /* if they are both literal then */
2315 /* rewrite the tree */
2316 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2318 tree->type = EX_VALUE;
2319 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2320 valFromType (RETYPE (tree)));
2321 tree->right = tree->left = NULL;
2322 TETYPE (tree) = getSpec (TTYPE (tree) =
2323 tree->opval.val->type);
2326 LRVAL (tree) = RRVAL (tree) = 1;
2327 TETYPE (tree) = getSpec (TTYPE (tree) =
2328 computeType (LTYPE (tree),
2332 /*------------------------------------------------------------------*/
2333 /*----------------------------*/
2335 /*----------------------------*/
2337 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2339 werror (E_BITWISE_OP);
2340 werror (W_CONTINUE, "left & right types are ");
2341 printTypeChain (LTYPE (tree), stderr);
2342 fprintf (stderr, ",");
2343 printTypeChain (RTYPE (tree), stderr);
2344 fprintf (stderr, "\n");
2345 goto errorTreeReturn;
2347 /* if they are both literal then */
2348 /* rewrite the tree */
2349 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2351 tree->type = EX_VALUE;
2352 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2353 valFromType (RETYPE (tree)));
2354 tree->right = tree->left = NULL;
2355 TETYPE (tree) = getSpec (TTYPE (tree) =
2356 tree->opval.val->type);
2359 LRVAL (tree) = RRVAL (tree) = 1;
2360 TETYPE (tree) = getSpec (TTYPE (tree) =
2361 computeType (LTYPE (tree),
2365 /*------------------------------------------------------------------*/
2366 /*----------------------------*/
2367 /* address dereference */
2368 /*----------------------------*/
2369 case '*': /* can be unary : if right is null then unary operation */
2372 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2374 werror (E_PTR_REQD);
2375 goto errorTreeReturn;
2380 werror (E_LVALUE_REQUIRED, "pointer deref");
2381 goto errorTreeReturn;
2383 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2384 LTYPE (tree)->next : NULL);
2385 TETYPE (tree) = getSpec (TTYPE (tree));
2386 tree->args = tree->left->args;
2387 tree->hasVargs = tree->left->hasVargs;
2388 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2392 /*------------------------------------------------------------------*/
2393 /*----------------------------*/
2394 /* multiplication */
2395 /*----------------------------*/
2396 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2398 werror (E_INVALID_OP, "multiplication");
2399 goto errorTreeReturn;
2402 /* if they are both literal then */
2403 /* rewrite the tree */
2404 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2406 tree->type = EX_VALUE;
2407 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2408 valFromType (RETYPE (tree)));
2409 tree->right = tree->left = NULL;
2410 TETYPE (tree) = getSpec (TTYPE (tree) =
2411 tree->opval.val->type);
2415 /* if left is a literal exchange left & right */
2416 if (IS_LITERAL (LTYPE (tree)))
2418 ast *tTree = tree->left;
2419 tree->left = tree->right;
2420 tree->right = tTree;
2423 LRVAL (tree) = RRVAL (tree) = 1;
2424 /* promote result to int if left & right are char
2425 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2426 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2427 TETYPE (tree) = getSpec (TTYPE (tree) =
2428 computeType (LTYPE (tree),
2430 SPEC_NOUN(TETYPE(tree)) = V_INT;
2432 TETYPE (tree) = getSpec (TTYPE (tree) =
2433 computeType (LTYPE (tree),
2438 /*------------------------------------------------------------------*/
2439 /*----------------------------*/
2440 /* unary '+' operator */
2441 /*----------------------------*/
2446 if (!IS_INTEGRAL (LTYPE (tree)))
2448 werror (E_UNARY_OP, '+');
2449 goto errorTreeReturn;
2452 /* if left is a literal then do it */
2453 if (IS_LITERAL (LTYPE (tree)))
2455 tree->type = EX_VALUE;
2456 tree->opval.val = valFromType (LETYPE (tree));
2458 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2462 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2466 /*------------------------------------------------------------------*/
2467 /*----------------------------*/
2469 /*----------------------------*/
2471 /* this is not a unary operation */
2472 /* if both pointers then problem */
2473 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2474 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2476 werror (E_PTR_PLUS_PTR);
2477 goto errorTreeReturn;
2480 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2481 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2483 werror (E_PLUS_INVALID, "+");
2484 goto errorTreeReturn;
2487 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2488 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2490 werror (E_PLUS_INVALID, "+");
2491 goto errorTreeReturn;
2493 /* if they are both literal then */
2494 /* rewrite the tree */
2495 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2497 tree->type = EX_VALUE;
2498 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2499 valFromType (RETYPE (tree)));
2500 tree->right = tree->left = NULL;
2501 TETYPE (tree) = getSpec (TTYPE (tree) =
2502 tree->opval.val->type);
2506 /* if the right is a pointer or left is a literal
2507 xchange left & right */
2508 if (IS_ARRAY (RTYPE (tree)) ||
2509 IS_PTR (RTYPE (tree)) ||
2510 IS_LITERAL (LTYPE (tree)))
2512 ast *tTree = tree->left;
2513 tree->left = tree->right;
2514 tree->right = tTree;
2517 LRVAL (tree) = RRVAL (tree) = 1;
2518 /* if the left is a pointer */
2519 if (IS_PTR (LTYPE (tree)))
2520 TETYPE (tree) = getSpec (TTYPE (tree) =
2523 TETYPE (tree) = getSpec (TTYPE (tree) =
2524 computeType (LTYPE (tree),
2528 /*------------------------------------------------------------------*/
2529 /*----------------------------*/
2531 /*----------------------------*/
2532 case '-': /* can be unary */
2533 /* if right is null then unary */
2537 if (!IS_ARITHMETIC (LTYPE (tree)))
2539 werror (E_UNARY_OP, tree->opval.op);
2540 goto errorTreeReturn;
2543 /* if left is a literal then do it */
2544 if (IS_LITERAL (LTYPE (tree)))
2546 tree->type = EX_VALUE;
2547 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2549 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2550 SPEC_USIGN(TETYPE(tree)) = 0;
2554 TTYPE (tree) = LTYPE (tree);
2558 /*------------------------------------------------------------------*/
2559 /*----------------------------*/
2561 /*----------------------------*/
2563 if (!(IS_PTR (LTYPE (tree)) ||
2564 IS_ARRAY (LTYPE (tree)) ||
2565 IS_ARITHMETIC (LTYPE (tree))))
2567 werror (E_PLUS_INVALID, "-");
2568 goto errorTreeReturn;
2571 if (!(IS_PTR (RTYPE (tree)) ||
2572 IS_ARRAY (RTYPE (tree)) ||
2573 IS_ARITHMETIC (RTYPE (tree))))
2575 werror (E_PLUS_INVALID, "-");
2576 goto errorTreeReturn;
2579 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2580 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2581 IS_INTEGRAL (RTYPE (tree))))
2583 werror (E_PLUS_INVALID, "-");
2584 goto errorTreeReturn;
2587 /* if they are both literal then */
2588 /* rewrite the tree */
2589 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2591 tree->type = EX_VALUE;
2592 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2593 valFromType (RETYPE (tree)));
2594 tree->right = tree->left = NULL;
2595 TETYPE (tree) = getSpec (TTYPE (tree) =
2596 tree->opval.val->type);
2600 /* if the left & right are equal then zero */
2601 if (isAstEqual (tree->left, tree->right))
2603 tree->type = EX_VALUE;
2604 tree->left = tree->right = NULL;
2605 tree->opval.val = constVal ("0");
2606 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2610 /* if both of them are pointers or arrays then */
2611 /* the result is going to be an integer */
2612 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2613 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2614 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2616 /* if only the left is a pointer */
2617 /* then result is a pointer */
2618 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2619 TETYPE (tree) = getSpec (TTYPE (tree) =
2622 TETYPE (tree) = getSpec (TTYPE (tree) =
2623 computeType (LTYPE (tree),
2625 LRVAL (tree) = RRVAL (tree) = 1;
2628 /*------------------------------------------------------------------*/
2629 /*----------------------------*/
2631 /*----------------------------*/
2633 /* can be only integral type */
2634 if (!IS_INTEGRAL (LTYPE (tree)))
2636 werror (E_UNARY_OP, tree->opval.op);
2637 goto errorTreeReturn;
2640 /* if left is a literal then do it */
2641 if (IS_LITERAL (LTYPE (tree)))
2643 tree->type = EX_VALUE;
2644 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2646 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2650 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2653 /*------------------------------------------------------------------*/
2654 /*----------------------------*/
2656 /*----------------------------*/
2658 /* can be pointer */
2659 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2660 !IS_PTR (LTYPE (tree)) &&
2661 !IS_ARRAY (LTYPE (tree)))
2663 werror (E_UNARY_OP, tree->opval.op);
2664 goto errorTreeReturn;
2667 /* if left is a literal then do it */
2668 if (IS_LITERAL (LTYPE (tree)))
2670 tree->type = EX_VALUE;
2671 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2673 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2677 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2680 /*------------------------------------------------------------------*/
2681 /*----------------------------*/
2683 /*----------------------------*/
2686 TTYPE (tree) = LTYPE (tree);
2687 TETYPE (tree) = LETYPE (tree);
2691 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2696 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2698 werror (E_SHIFT_OP_INVALID);
2699 werror (W_CONTINUE, "left & right types are ");
2700 printTypeChain (LTYPE (tree), stderr);
2701 fprintf (stderr, ",");
2702 printTypeChain (RTYPE (tree), stderr);
2703 fprintf (stderr, "\n");
2704 goto errorTreeReturn;
2707 /* if they are both literal then */
2708 /* rewrite the tree */
2709 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2711 tree->type = EX_VALUE;
2712 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2713 valFromType (RETYPE (tree)),
2714 (tree->opval.op == LEFT_OP ? 1 : 0));
2715 tree->right = tree->left = NULL;
2716 TETYPE (tree) = getSpec (TTYPE (tree) =
2717 tree->opval.val->type);
2720 /* if only the right side is a literal & we are
2721 shifting more than size of the left operand then zero */
2722 if (IS_LITERAL (RTYPE (tree)) &&
2723 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2724 (getSize (LTYPE (tree)) * 8))
2726 werror (W_SHIFT_CHANGED,
2727 (tree->opval.op == LEFT_OP ? "left" : "right"));
2728 tree->type = EX_VALUE;
2729 tree->left = tree->right = NULL;
2730 tree->opval.val = constVal ("0");
2731 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2734 LRVAL (tree) = RRVAL (tree) = 1;
2735 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2737 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2741 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2745 /*------------------------------------------------------------------*/
2746 /*----------------------------*/
2748 /*----------------------------*/
2749 case CAST: /* change the type */
2750 /* cannot cast to an aggregate type */
2751 if (IS_AGGREGATE (LTYPE (tree)))
2753 werror (E_CAST_ILLEGAL);
2754 goto errorTreeReturn;
2757 /* make sure the type is complete and sane */
2758 checkTypeSanity(LETYPE(tree), "(cast)");
2760 /* if the right is a literal replace the tree */
2761 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2763 tree->type = EX_VALUE;
2765 valCastLiteral (LTYPE (tree),
2766 floatFromVal (valFromType (RETYPE (tree))));
2769 TTYPE (tree) = tree->opval.val->type;
2770 tree->values.literalFromCast = 1;
2774 TTYPE (tree) = LTYPE (tree);
2778 TETYPE (tree) = getSpec (TTYPE (tree));
2782 /*------------------------------------------------------------------*/
2783 /*----------------------------*/
2784 /* logical &&, || */
2785 /*----------------------------*/
2788 /* each must me arithmetic type or be a pointer */
2789 if (!IS_PTR (LTYPE (tree)) &&
2790 !IS_ARRAY (LTYPE (tree)) &&
2791 !IS_INTEGRAL (LTYPE (tree)))
2793 werror (E_COMPARE_OP);
2794 goto errorTreeReturn;
2797 if (!IS_PTR (RTYPE (tree)) &&
2798 !IS_ARRAY (RTYPE (tree)) &&
2799 !IS_INTEGRAL (RTYPE (tree)))
2801 werror (E_COMPARE_OP);
2802 goto errorTreeReturn;
2804 /* if they are both literal then */
2805 /* rewrite the tree */
2806 if (IS_LITERAL (RTYPE (tree)) &&
2807 IS_LITERAL (LTYPE (tree)))
2809 tree->type = EX_VALUE;
2810 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2811 valFromType (RETYPE (tree)),
2813 tree->right = tree->left = NULL;
2814 TETYPE (tree) = getSpec (TTYPE (tree) =
2815 tree->opval.val->type);
2818 LRVAL (tree) = RRVAL (tree) = 1;
2819 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2822 /*------------------------------------------------------------------*/
2823 /*----------------------------*/
2824 /* comparison operators */
2825 /*----------------------------*/
2833 ast *lt = optimizeCompare (tree);
2839 /* if they are pointers they must be castable */
2840 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2842 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2844 werror (E_COMPARE_OP);
2845 fprintf (stderr, "comparing type ");
2846 printTypeChain (LTYPE (tree), stderr);
2847 fprintf (stderr, "to type ");
2848 printTypeChain (RTYPE (tree), stderr);
2849 fprintf (stderr, "\n");
2850 goto errorTreeReturn;
2853 /* else they should be promotable to one another */
2856 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2857 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2859 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2861 werror (E_COMPARE_OP);
2862 fprintf (stderr, "comparing type ");
2863 printTypeChain (LTYPE (tree), stderr);
2864 fprintf (stderr, "to type ");
2865 printTypeChain (RTYPE (tree), stderr);
2866 fprintf (stderr, "\n");
2867 goto errorTreeReturn;
2871 /* if they are both literal then */
2872 /* rewrite the tree */
2873 if (IS_LITERAL (RTYPE (tree)) &&
2874 IS_LITERAL (LTYPE (tree)))
2876 tree->type = EX_VALUE;
2877 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2878 valFromType (RETYPE (tree)),
2880 tree->right = tree->left = NULL;
2881 TETYPE (tree) = getSpec (TTYPE (tree) =
2882 tree->opval.val->type);
2885 LRVAL (tree) = RRVAL (tree) = 1;
2886 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2889 /*------------------------------------------------------------------*/
2890 /*----------------------------*/
2892 /*----------------------------*/
2893 case SIZEOF: /* evaluate wihout code generation */
2894 /* change the type to a integer */
2895 tree->type = EX_VALUE;
2896 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2897 tree->opval.val = constVal (buffer);
2898 tree->right = tree->left = NULL;
2899 TETYPE (tree) = getSpec (TTYPE (tree) =
2900 tree->opval.val->type);
2903 /*------------------------------------------------------------------*/
2904 /*----------------------------*/
2905 /* conditional operator '?' */
2906 /*----------------------------*/
2908 /* the type is value of the colon operator (on the right) */
2909 assert(IS_COLON_OP(tree->right));
2910 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2911 TETYPE (tree) = getSpec (TTYPE (tree));
2915 /* if they don't match we have a problem */
2916 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2918 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2919 goto errorTreeReturn;
2922 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2923 TETYPE (tree) = getSpec (TTYPE (tree));
2927 /*------------------------------------------------------------------*/
2928 /*----------------------------*/
2929 /* assignment operators */
2930 /*----------------------------*/
2933 /* for these it must be both must be integral */
2934 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2935 !IS_ARITHMETIC (RTYPE (tree)))
2937 werror (E_OPS_INTEGRAL);
2938 goto errorTreeReturn;
2941 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2943 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2944 werror (E_CODE_WRITE, " ");
2948 werror (E_LVALUE_REQUIRED, "*= or /=");
2949 goto errorTreeReturn;
2962 /* for these it must be both must be integral */
2963 if (!IS_INTEGRAL (LTYPE (tree)) ||
2964 !IS_INTEGRAL (RTYPE (tree)))
2966 werror (E_OPS_INTEGRAL);
2967 goto errorTreeReturn;
2970 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2972 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2973 werror (E_CODE_WRITE, " ");
2977 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2978 goto errorTreeReturn;
2986 /*------------------------------------------------------------------*/
2987 /*----------------------------*/
2989 /*----------------------------*/
2991 if (!(IS_PTR (LTYPE (tree)) ||
2992 IS_ARITHMETIC (LTYPE (tree))))
2994 werror (E_PLUS_INVALID, "-=");
2995 goto errorTreeReturn;
2998 if (!(IS_PTR (RTYPE (tree)) ||
2999 IS_ARITHMETIC (RTYPE (tree))))
3001 werror (E_PLUS_INVALID, "-=");
3002 goto errorTreeReturn;
3005 TETYPE (tree) = getSpec (TTYPE (tree) =
3006 computeType (LTYPE (tree),
3009 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3010 werror (E_CODE_WRITE, " ");
3014 werror (E_LVALUE_REQUIRED, "-=");
3015 goto errorTreeReturn;
3023 /*------------------------------------------------------------------*/
3024 /*----------------------------*/
3026 /*----------------------------*/
3028 /* this is not a unary operation */
3029 /* if both pointers then problem */
3030 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3032 werror (E_PTR_PLUS_PTR);
3033 goto errorTreeReturn;
3036 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3038 werror (E_PLUS_INVALID, "+=");
3039 goto errorTreeReturn;
3042 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3044 werror (E_PLUS_INVALID, "+=");
3045 goto errorTreeReturn;
3048 TETYPE (tree) = getSpec (TTYPE (tree) =
3049 computeType (LTYPE (tree),
3052 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3053 werror (E_CODE_WRITE, " ");
3057 werror (E_LVALUE_REQUIRED, "+=");
3058 goto errorTreeReturn;
3061 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3062 tree->opval.op = '=';
3068 /*------------------------------------------------------------------*/
3069 /*----------------------------*/
3070 /* straight assignemnt */
3071 /*----------------------------*/
3073 /* cannot be an aggregate */
3074 if (IS_AGGREGATE (LTYPE (tree)))
3076 werror (E_AGGR_ASSIGN);
3077 goto errorTreeReturn;
3080 /* they should either match or be castable */
3081 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3083 werror (E_TYPE_MISMATCH, "assignment", " ");
3084 fprintf (stderr, "type --> '");
3085 printTypeChain (RTYPE (tree), stderr);
3086 fprintf (stderr, "' ");
3087 fprintf (stderr, "assigned to type --> '");
3088 printTypeChain (LTYPE (tree), stderr);
3089 fprintf (stderr, "'\n");
3090 goto errorTreeReturn;
3093 /* if the left side of the tree is of type void
3094 then report error */
3095 if (IS_VOID (LTYPE (tree)))
3097 werror (E_CAST_ZERO);
3098 fprintf (stderr, "type --> '");
3099 printTypeChain (RTYPE (tree), stderr);
3100 fprintf (stderr, "' ");
3101 fprintf (stderr, "assigned to type --> '");
3102 printTypeChain (LTYPE (tree), stderr);
3103 fprintf (stderr, "'\n");
3106 /* extra checks for pointer types */
3107 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
3108 !IS_GENPTR (LTYPE (tree)))
3110 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
3111 werror (W_PTR_ASSIGN);
3114 TETYPE (tree) = getSpec (TTYPE (tree) =
3118 if (!tree->initMode ) {
3119 if (IS_CONSTANT (LETYPE (tree))) {
3120 werror (E_CODE_WRITE, " ");
3125 werror (E_LVALUE_REQUIRED, "=");
3126 goto errorTreeReturn;
3133 /*------------------------------------------------------------------*/
3134 /*----------------------------*/
3135 /* comma operator */
3136 /*----------------------------*/
3138 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3141 /*------------------------------------------------------------------*/
3142 /*----------------------------*/
3144 /*----------------------------*/
3148 if (processParms (tree->left,
3150 tree->right, &parmNumber, TRUE))
3151 goto errorTreeReturn;
3153 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3155 tree->left->args = reverseVal (tree->left->args);
3156 reverseParms (tree->right);
3159 tree->args = tree->left->args;
3160 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3163 /*------------------------------------------------------------------*/
3164 /*----------------------------*/
3165 /* return statement */
3166 /*----------------------------*/
3171 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3173 werror (W_RETURN_MISMATCH);
3174 goto errorTreeReturn;
3177 if (IS_VOID (currFunc->type->next)
3179 !IS_VOID (RTYPE (tree)))
3181 werror (E_FUNC_VOID);
3182 goto errorTreeReturn;
3185 /* if there is going to be a casing required then add it */
3186 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3188 #if 0 && defined DEMAND_INTEGER_PROMOTION
3189 if (IS_INTEGRAL (currFunc->type->next))
3191 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3197 decorateType (newNode (CAST,
3198 newAst_LINK (copyLinkChain (currFunc->type->next)),
3208 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3210 werror (E_VOID_FUNC, currFunc->name);
3211 goto errorTreeReturn;
3214 TTYPE (tree) = TETYPE (tree) = NULL;
3217 /*------------------------------------------------------------------*/
3218 /*----------------------------*/
3219 /* switch statement */
3220 /*----------------------------*/
3222 /* the switch value must be an integer */
3223 if (!IS_INTEGRAL (LTYPE (tree)))
3225 werror (E_SWITCH_NON_INTEGER);
3226 goto errorTreeReturn;
3229 TTYPE (tree) = TETYPE (tree) = NULL;
3232 /*------------------------------------------------------------------*/
3233 /*----------------------------*/
3235 /*----------------------------*/
3237 tree->left = backPatchLabels (tree->left,
3240 TTYPE (tree) = TETYPE (tree) = NULL;
3243 /*------------------------------------------------------------------*/
3244 /*----------------------------*/
3246 /*----------------------------*/
3249 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3250 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3251 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3253 /* if the for loop is reversible then
3254 reverse it otherwise do what we normally
3260 if (isLoopReversible (tree, &sym, &init, &end))
3261 return reverseLoop (tree, sym, init, end);
3263 return decorateType (createFor (AST_FOR (tree, trueLabel),
3264 AST_FOR (tree, continueLabel),
3265 AST_FOR (tree, falseLabel),
3266 AST_FOR (tree, condLabel),
3267 AST_FOR (tree, initExpr),
3268 AST_FOR (tree, condExpr),
3269 AST_FOR (tree, loopExpr),
3273 TTYPE (tree) = TETYPE (tree) = NULL;
3277 /* some error found this tree will be killed */
3279 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3280 tree->opval.op = NULLOP;
3286 /*-----------------------------------------------------------------*/
3287 /* sizeofOp - processes size of operation */
3288 /*-----------------------------------------------------------------*/
3290 sizeofOp (sym_link * type)
3294 /* make sure the type is complete and sane */
3295 checkTypeSanity(type, "(sizeof)");
3297 /* get the size and convert it to character */
3298 sprintf (buff, "%d", getSize (type));
3300 /* now convert into value */
3301 return constVal (buff);
3305 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3306 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3307 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3308 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3309 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3310 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3311 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3313 /*-----------------------------------------------------------------*/
3314 /* backPatchLabels - change and or not operators to flow control */
3315 /*-----------------------------------------------------------------*/
3317 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3323 if (!(IS_ANDORNOT (tree)))
3326 /* if this an and */
3329 static int localLbl = 0;
3332 sprintf (buffer, "_and_%d", localLbl++);
3333 localLabel = newSymbol (buffer, NestLevel);
3335 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3337 /* if left is already a IFX then just change the if true label in that */
3338 if (!IS_IFX (tree->left))
3339 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3341 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3342 /* right is a IFX then just join */
3343 if (IS_IFX (tree->right))
3344 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3346 tree->right = createLabel (localLabel, tree->right);
3347 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3349 return newNode (NULLOP, tree->left, tree->right);
3352 /* if this is an or operation */
3355 static int localLbl = 0;
3358 sprintf (buffer, "_or_%d", localLbl++);
3359 localLabel = newSymbol (buffer, NestLevel);
3361 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3363 /* if left is already a IFX then just change the if true label in that */
3364 if (!IS_IFX (tree->left))
3365 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3367 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3368 /* right is a IFX then just join */
3369 if (IS_IFX (tree->right))
3370 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3372 tree->right = createLabel (localLabel, tree->right);
3373 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3375 return newNode (NULLOP, tree->left, tree->right);
3381 int wasnot = IS_NOT (tree->left);
3382 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3384 /* if the left is already a IFX */
3385 if (!IS_IFX (tree->left))
3386 tree->left = newNode (IFX, tree->left, NULL);
3390 tree->left->trueLabel = trueLabel;
3391 tree->left->falseLabel = falseLabel;
3395 tree->left->trueLabel = falseLabel;
3396 tree->left->falseLabel = trueLabel;
3403 tree->trueLabel = trueLabel;
3404 tree->falseLabel = falseLabel;
3411 /*-----------------------------------------------------------------*/
3412 /* createBlock - create expression tree for block */
3413 /*-----------------------------------------------------------------*/
3415 createBlock (symbol * decl, ast * body)
3419 /* if the block has nothing */
3423 ex = newNode (BLOCK, NULL, body);
3424 ex->values.sym = decl;
3426 ex->right = ex->right;
3432 /*-----------------------------------------------------------------*/
3433 /* createLabel - creates the expression tree for labels */
3434 /*-----------------------------------------------------------------*/
3436 createLabel (symbol * label, ast * stmnt)
3439 char name[SDCC_NAME_MAX + 1];
3442 /* must create fresh symbol if the symbol name */
3443 /* exists in the symbol table, since there can */
3444 /* be a variable with the same name as the labl */
3445 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3446 (csym->level == label->level))
3447 label = newSymbol (label->name, label->level);
3449 /* change the name before putting it in add _ */
3450 sprintf (name, "%s", label->name);
3452 /* put the label in the LabelSymbol table */
3453 /* but first check if a label of the same */
3455 if ((csym = findSym (LabelTab, NULL, name)))
3456 werror (E_DUPLICATE_LABEL, label->name);
3458 addSym (LabelTab, label, name, label->level, 0, 0);
3461 label->key = labelKey++;
3462 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3468 /*-----------------------------------------------------------------*/
3469 /* createCase - generates the parsetree for a case statement */
3470 /*-----------------------------------------------------------------*/
3472 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3474 char caseLbl[SDCC_NAME_MAX + 1];
3478 /* if the switch statement does not exist */
3479 /* then case is out of context */
3482 werror (E_CASE_CONTEXT);
3486 caseVal = decorateType (resolveSymbols (caseVal));
3487 /* if not a constant then error */
3488 if (!IS_LITERAL (caseVal->ftype))
3490 werror (E_CASE_CONSTANT);
3494 /* if not a integer than error */
3495 if (!IS_INTEGRAL (caseVal->ftype))
3497 werror (E_CASE_NON_INTEGER);
3501 /* find the end of the switch values chain */
3502 if (!(val = swStat->values.switchVals.swVals))
3503 swStat->values.switchVals.swVals = caseVal->opval.val;
3506 /* also order the cases according to value */
3508 int cVal = (int) floatFromVal (caseVal->opval.val);
3509 while (val && (int) floatFromVal (val) < cVal)
3515 /* if we reached the end then */
3518 pval->next = caseVal->opval.val;
3522 /* we found a value greater than */
3523 /* the current value we must add this */
3524 /* before the value */
3525 caseVal->opval.val->next = val;
3527 /* if this was the first in chain */
3528 if (swStat->values.switchVals.swVals == val)
3529 swStat->values.switchVals.swVals =
3532 pval->next = caseVal->opval.val;
3537 /* create the case label */
3538 sprintf (caseLbl, "_case_%d_%d",
3539 swStat->values.switchVals.swNum,
3540 (int) floatFromVal (caseVal->opval.val));
3542 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3547 /*-----------------------------------------------------------------*/
3548 /* createDefault - creates the parse tree for the default statement */
3549 /*-----------------------------------------------------------------*/
3551 createDefault (ast * swStat, ast * stmnt)
3553 char defLbl[SDCC_NAME_MAX + 1];
3555 /* if the switch statement does not exist */
3556 /* then case is out of context */
3559 werror (E_CASE_CONTEXT);
3563 /* turn on the default flag */
3564 swStat->values.switchVals.swDefault = 1;
3566 /* create the label */
3567 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3568 return createLabel (newSymbol (defLbl, 0), stmnt);
3571 /*-----------------------------------------------------------------*/
3572 /* createIf - creates the parsetree for the if statement */
3573 /*-----------------------------------------------------------------*/
3575 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3577 static int Lblnum = 0;
3579 symbol *ifTrue, *ifFalse, *ifEnd;
3581 /* if neither exists */
3582 if (!elseBody && !ifBody)
3585 /* create the labels */
3586 sprintf (buffer, "_iffalse_%d", Lblnum);
3587 ifFalse = newSymbol (buffer, NestLevel);
3588 /* if no else body then end == false */
3593 sprintf (buffer, "_ifend_%d", Lblnum);
3594 ifEnd = newSymbol (buffer, NestLevel);
3597 sprintf (buffer, "_iftrue_%d", Lblnum);
3598 ifTrue = newSymbol (buffer, NestLevel);
3602 /* attach the ifTrue label to the top of it body */
3603 ifBody = createLabel (ifTrue, ifBody);
3604 /* attach a goto end to the ifBody if else is present */
3607 ifBody = newNode (NULLOP, ifBody,
3609 newAst_VALUE (symbolVal (ifEnd)),
3611 /* put the elseLabel on the else body */
3612 elseBody = createLabel (ifFalse, elseBody);
3613 /* out the end at the end of the body */
3614 elseBody = newNode (NULLOP,
3616 createLabel (ifEnd, NULL));
3620 ifBody = newNode (NULLOP, ifBody,
3621 createLabel (ifFalse, NULL));
3623 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3624 if (IS_IFX (condAst))
3627 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3629 return newNode (NULLOP, ifTree,
3630 newNode (NULLOP, ifBody, elseBody));
3634 /*-----------------------------------------------------------------*/
3635 /* createDo - creates parse tree for do */
3638 /* _docontinue_n: */
3639 /* condition_expression +-> trueLabel -> _dobody_n */
3641 /* +-> falseLabel-> _dobreak_n */
3643 /*-----------------------------------------------------------------*/
3645 createDo (symbol * trueLabel, symbol * continueLabel,
3646 symbol * falseLabel, ast * condAst, ast * doBody)
3651 /* if the body does not exist then it is simple */
3654 condAst = backPatchLabels (condAst, continueLabel, NULL);
3655 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3656 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3657 doTree->trueLabel = continueLabel;
3658 doTree->falseLabel = NULL;
3662 /* otherwise we have a body */
3663 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3665 /* attach the body label to the top */
3666 doBody = createLabel (trueLabel, doBody);
3667 /* attach the continue label to end of body */
3668 doBody = newNode (NULLOP, doBody,
3669 createLabel (continueLabel, NULL));
3671 /* now put the break label at the end */
3672 if (IS_IFX (condAst))
3675 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3677 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3679 /* putting it together */
3680 return newNode (NULLOP, doBody, doTree);
3683 /*-----------------------------------------------------------------*/
3684 /* createFor - creates parse tree for 'for' statement */
3687 /* condExpr +-> trueLabel -> _forbody_n */
3689 /* +-> falseLabel-> _forbreak_n */
3692 /* _forcontinue_n: */
3694 /* goto _forcond_n ; */
3696 /*-----------------------------------------------------------------*/
3698 createFor (symbol * trueLabel, symbol * continueLabel,
3699 symbol * falseLabel, symbol * condLabel,
3700 ast * initExpr, ast * condExpr, ast * loopExpr,
3705 /* if loopexpression not present then we can generate it */
3706 /* the same way as a while */
3708 return newNode (NULLOP, initExpr,
3709 createWhile (trueLabel, continueLabel,
3710 falseLabel, condExpr, forBody));
3711 /* vanilla for statement */
3712 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3714 if (condExpr && !IS_IFX (condExpr))
3715 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3718 /* attach condition label to condition */
3719 condExpr = createLabel (condLabel, condExpr);
3721 /* attach body label to body */
3722 forBody = createLabel (trueLabel, forBody);
3724 /* attach continue to forLoop expression & attach */
3725 /* goto the forcond @ and of loopExpression */
3726 loopExpr = createLabel (continueLabel,
3730 newAst_VALUE (symbolVal (condLabel)),
3732 /* now start putting them together */
3733 forTree = newNode (NULLOP, initExpr, condExpr);
3734 forTree = newNode (NULLOP, forTree, forBody);
3735 forTree = newNode (NULLOP, forTree, loopExpr);
3736 /* finally add the break label */
3737 forTree = newNode (NULLOP, forTree,
3738 createLabel (falseLabel, NULL));
3742 /*-----------------------------------------------------------------*/
3743 /* createWhile - creates parse tree for while statement */
3744 /* the while statement will be created as follows */
3746 /* _while_continue_n: */
3747 /* condition_expression +-> trueLabel -> _while_boby_n */
3749 /* +-> falseLabel -> _while_break_n */
3750 /* _while_body_n: */
3752 /* goto _while_continue_n */
3753 /* _while_break_n: */
3754 /*-----------------------------------------------------------------*/
3756 createWhile (symbol * trueLabel, symbol * continueLabel,
3757 symbol * falseLabel, ast * condExpr, ast * whileBody)
3761 /* put the continue label */
3762 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3763 condExpr = createLabel (continueLabel, condExpr);
3764 condExpr->lineno = 0;
3766 /* put the body label in front of the body */
3767 whileBody = createLabel (trueLabel, whileBody);
3768 whileBody->lineno = 0;
3769 /* put a jump to continue at the end of the body */
3770 /* and put break label at the end of the body */
3771 whileBody = newNode (NULLOP,
3774 newAst_VALUE (symbolVal (continueLabel)),
3775 createLabel (falseLabel, NULL)));
3777 /* put it all together */
3778 if (IS_IFX (condExpr))
3779 whileTree = condExpr;
3782 whileTree = newNode (IFX, condExpr, NULL);
3783 /* put the true & false labels in place */
3784 whileTree->trueLabel = trueLabel;
3785 whileTree->falseLabel = falseLabel;
3788 return newNode (NULLOP, whileTree, whileBody);
3791 /*-----------------------------------------------------------------*/
3792 /* optimizeGetHbit - get highest order bit of the expression */
3793 /*-----------------------------------------------------------------*/
3795 optimizeGetHbit (ast * tree)
3798 /* if this is not a bit and */
3799 if (!IS_BITAND (tree))
3802 /* will look for tree of the form
3803 ( expr >> ((sizeof expr) -1) ) & 1 */
3804 if (!IS_AST_LIT_VALUE (tree->right))
3807 if (AST_LIT_VALUE (tree->right) != 1)
3810 if (!IS_RIGHT_OP (tree->left))
3813 if (!IS_AST_LIT_VALUE (tree->left->right))
3816 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3817 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3820 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3824 /*-----------------------------------------------------------------*/
3825 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3826 /*-----------------------------------------------------------------*/
3828 optimizeRRCRLC (ast * root)
3830 /* will look for trees of the form
3831 (?expr << 1) | (?expr >> 7) or
3832 (?expr >> 7) | (?expr << 1) will make that
3833 into a RLC : operation ..
3835 (?expr >> 1) | (?expr << 7) or
3836 (?expr << 7) | (?expr >> 1) will make that
3837 into a RRC operation
3838 note : by 7 I mean (number of bits required to hold the
3840 /* if the root operations is not a | operation the not */
3841 if (!IS_BITOR (root))
3844 /* I have to think of a better way to match patterns this sucks */
3845 /* that aside let start looking for the first case : I use a the
3846 negative check a lot to improve the efficiency */
3847 /* (?expr << 1) | (?expr >> 7) */
3848 if (IS_LEFT_OP (root->left) &&
3849 IS_RIGHT_OP (root->right))
3852 if (!SPEC_USIGN (TETYPE (root->left->left)))
3855 if (!IS_AST_LIT_VALUE (root->left->right) ||
3856 !IS_AST_LIT_VALUE (root->right->right))
3859 /* make sure it is the same expression */
3860 if (!isAstEqual (root->left->left,
3864 if (AST_LIT_VALUE (root->left->right) != 1)
3867 if (AST_LIT_VALUE (root->right->right) !=
3868 (getSize (TTYPE (root->left->left)) * 8 - 1))
3871 /* whew got the first case : create the AST */
3872 return newNode (RLC, root->left->left, NULL);
3876 /* check for second case */
3877 /* (?expr >> 7) | (?expr << 1) */
3878 if (IS_LEFT_OP (root->right) &&
3879 IS_RIGHT_OP (root->left))
3882 if (!SPEC_USIGN (TETYPE (root->left->left)))
3885 if (!IS_AST_LIT_VALUE (root->left->right) ||
3886 !IS_AST_LIT_VALUE (root->right->right))
3889 /* make sure it is the same symbol */
3890 if (!isAstEqual (root->left->left,
3894 if (AST_LIT_VALUE (root->right->right) != 1)
3897 if (AST_LIT_VALUE (root->left->right) !=
3898 (getSize (TTYPE (root->left->left)) * 8 - 1))
3901 /* whew got the first case : create the AST */
3902 return newNode (RLC, root->left->left, NULL);
3907 /* third case for RRC */
3908 /* (?symbol >> 1) | (?symbol << 7) */
3909 if (IS_LEFT_OP (root->right) &&
3910 IS_RIGHT_OP (root->left))
3913 if (!SPEC_USIGN (TETYPE (root->left->left)))
3916 if (!IS_AST_LIT_VALUE (root->left->right) ||
3917 !IS_AST_LIT_VALUE (root->right->right))
3920 /* make sure it is the same symbol */
3921 if (!isAstEqual (root->left->left,
3925 if (AST_LIT_VALUE (root->left->right) != 1)
3928 if (AST_LIT_VALUE (root->right->right) !=
3929 (getSize (TTYPE (root->left->left)) * 8 - 1))
3932 /* whew got the first case : create the AST */
3933 return newNode (RRC, root->left->left, NULL);
3937 /* fourth and last case for now */
3938 /* (?symbol << 7) | (?symbol >> 1) */
3939 if (IS_RIGHT_OP (root->right) &&
3940 IS_LEFT_OP (root->left))
3943 if (!SPEC_USIGN (TETYPE (root->left->left)))
3946 if (!IS_AST_LIT_VALUE (root->left->right) ||
3947 !IS_AST_LIT_VALUE (root->right->right))
3950 /* make sure it is the same symbol */
3951 if (!isAstEqual (root->left->left,
3955 if (AST_LIT_VALUE (root->right->right) != 1)
3958 if (AST_LIT_VALUE (root->left->right) !=
3959 (getSize (TTYPE (root->left->left)) * 8 - 1))
3962 /* whew got the first case : create the AST */
3963 return newNode (RRC, root->left->left, NULL);
3967 /* not found return root */
3971 /*-----------------------------------------------------------------*/
3972 /* optimizeCompare - otimizes compares for bit variables */
3973 /*-----------------------------------------------------------------*/
3975 optimizeCompare (ast * root)
3977 ast *optExpr = NULL;
3980 unsigned int litValue;
3982 /* if nothing then return nothing */
3986 /* if not a compare op then do leaves */
3987 if (!IS_COMPARE_OP (root))
3989 root->left = optimizeCompare (root->left);
3990 root->right = optimizeCompare (root->right);
3994 /* if left & right are the same then depending
3995 of the operation do */
3996 if (isAstEqual (root->left, root->right))
3998 switch (root->opval.op)
4003 optExpr = newAst_VALUE (constVal ("0"));
4008 optExpr = newAst_VALUE (constVal ("1"));
4012 return decorateType (optExpr);
4015 vleft = (root->left->type == EX_VALUE ?
4016 root->left->opval.val : NULL);
4018 vright = (root->right->type == EX_VALUE ?
4019 root->right->opval.val : NULL);
4021 /* if left is a BITVAR in BITSPACE */
4022 /* and right is a LITERAL then opt- */
4023 /* imize else do nothing */
4024 if (vleft && vright &&
4025 IS_BITVAR (vleft->etype) &&
4026 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4027 IS_LITERAL (vright->etype))
4030 /* if right side > 1 then comparison may never succeed */
4031 if ((litValue = (int) floatFromVal (vright)) > 1)
4033 werror (W_BAD_COMPARE);
4039 switch (root->opval.op)
4041 case '>': /* bit value greater than 1 cannot be */
4042 werror (W_BAD_COMPARE);
4046 case '<': /* bit value < 1 means 0 */
4048 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4051 case LE_OP: /* bit value <= 1 means no check */
4052 optExpr = newAst_VALUE (vright);
4055 case GE_OP: /* bit value >= 1 means only check for = */
4057 optExpr = newAst_VALUE (vleft);
4062 { /* literal is zero */
4063 switch (root->opval.op)
4065 case '<': /* bit value < 0 cannot be */
4066 werror (W_BAD_COMPARE);
4070 case '>': /* bit value > 0 means 1 */
4072 optExpr = newAst_VALUE (vleft);
4075 case LE_OP: /* bit value <= 0 means no check */
4076 case GE_OP: /* bit value >= 0 means no check */
4077 werror (W_BAD_COMPARE);
4081 case EQ_OP: /* bit == 0 means ! of bit */
4082 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4086 return decorateType (resolveSymbols (optExpr));
4087 } /* end-of-if of BITVAR */
4092 /*-----------------------------------------------------------------*/
4093 /* addSymToBlock : adds the symbol to the first block we find */
4094 /*-----------------------------------------------------------------*/
4096 addSymToBlock (symbol * sym, ast * tree)
4098 /* reached end of tree or a leaf */
4099 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4103 if (IS_AST_OP (tree) &&
4104 tree->opval.op == BLOCK)
4107 symbol *lsym = copySymbol (sym);
4109 lsym->next = AST_VALUES (tree, sym);
4110 AST_VALUES (tree, sym) = lsym;
4114 addSymToBlock (sym, tree->left);
4115 addSymToBlock (sym, tree->right);
4118 /*-----------------------------------------------------------------*/
4119 /* processRegParms - do processing for register parameters */
4120 /*-----------------------------------------------------------------*/
4122 processRegParms (value * args, ast * body)
4126 if (IS_REGPARM (args->etype))
4127 addSymToBlock (args->sym, body);
4132 /*-----------------------------------------------------------------*/
4133 /* resetParmKey - resets the operandkeys for the symbols */
4134 /*-----------------------------------------------------------------*/
4135 DEFSETFUNC (resetParmKey)
4146 /*-----------------------------------------------------------------*/
4147 /* createFunction - This is the key node that calls the iCode for */
4148 /* generating the code for a function. Note code */
4149 /* is generated function by function, later when */
4150 /* add inter-procedural analysis this will change */
4151 /*-----------------------------------------------------------------*/
4153 createFunction (symbol * name, ast * body)
4159 iCode *piCode = NULL;
4161 /* if check function return 0 then some problem */
4162 if (checkFunction (name) == 0)
4165 /* create a dummy block if none exists */
4167 body = newNode (BLOCK, NULL, NULL);
4171 /* check if the function name already in the symbol table */
4172 if ((csym = findSym (SymbolTab, NULL, name->name)))
4175 /* special case for compiler defined functions
4176 we need to add the name to the publics list : this
4177 actually means we are now compiling the compiler
4181 addSet (&publics, name);
4187 allocVariables (name);
4189 name->lastLine = yylineno;
4191 processFuncArgs (currFunc, 0);
4193 /* set the stack pointer */
4194 /* PENDING: check this for the mcs51 */
4195 stackPtr = -port->stack.direction * port->stack.call_overhead;
4196 if (IS_ISR (name->etype))
4197 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4198 if (IS_RENT (name->etype) || options.stackAuto)
4199 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4201 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4203 fetype = getSpec (name->type); /* get the specifier for the function */
4204 /* if this is a reentrant function then */
4205 if (IS_RENT (fetype))
4208 allocParms (name->args); /* allocate the parameters */
4210 /* do processing for parameters that are passed in registers */
4211 processRegParms (name->args, body);
4213 /* set the stack pointer */
4217 /* allocate & autoinit the block variables */
4218 processBlockVars (body, &stack, ALLOCATE);
4220 /* save the stack information */
4221 if (options.useXstack)
4222 name->xstack = SPEC_STAK (fetype) = stack;
4224 name->stack = SPEC_STAK (fetype) = stack;
4226 /* name needs to be mangled */
4227 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4229 body = resolveSymbols (body); /* resolve the symbols */
4230 body = decorateType (body); /* propagateType & do semantic checks */
4232 ex = newAst_VALUE (symbolVal (name)); /* create name */
4233 ex = newNode (FUNCTION, ex, body);
4234 ex->values.args = name->args;
4238 werror (E_FUNC_NO_CODE, name->name);
4242 /* create the node & generate intermediate code */
4244 codeOutFile = code->oFile;
4245 piCode = iCodeFromAst (ex);
4249 werror (E_FUNC_NO_CODE, name->name);
4253 eBBlockFromiCode (piCode);
4255 /* if there are any statics then do them */
4258 GcurMemmap = statsg;
4259 codeOutFile = statsg->oFile;
4260 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4266 /* dealloc the block variables */
4267 processBlockVars (body, &stack, DEALLOCATE);
4268 /* deallocate paramaters */
4269 deallocParms (name->args);
4271 if (IS_RENT (fetype))
4274 /* we are done freeup memory & cleanup */
4279 addSet (&operKeyReset, name);
4280 applyToSet (operKeyReset, resetParmKey);
4283 cdbStructBlock (1, cdbFile);
4285 cleanUpLevel (LabelTab, 0);
4286 cleanUpBlock (StructTab, 1);
4287 cleanUpBlock (TypedefTab, 1);
4289 xstack->syms = NULL;
4290 istack->syms = NULL;
4295 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4296 /*-----------------------------------------------------------------*/
4297 /* ast_print : prints the ast (for debugging purposes) */
4298 /*-----------------------------------------------------------------*/
4300 void ast_print (ast * tree, FILE *outfile, int indent)
4305 /* can print only decorated trees */
4306 if (!tree->decorated) return;
4308 /* if any child is an error | this one is an error do nothing */
4309 if (tree->isError ||
4310 (tree->left && tree->left->isError) ||
4311 (tree->right && tree->right->isError)) {
4312 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4316 /* print the line */
4317 /* if not block & function */
4318 if (tree->type == EX_OP &&
4319 (tree->opval.op != FUNCTION &&
4320 tree->opval.op != BLOCK &&
4321 tree->opval.op != NULLOP)) {
4324 if (tree->opval.op == FUNCTION) {
4325 fprintf(outfile,"FUNCTION (%p) type (",tree);
4326 printTypeChain (tree->ftype,outfile);
4327 fprintf(outfile,")\n");
4328 ast_print(tree->left,outfile,indent+4);
4329 ast_print(tree->right,outfile,indent+4);
4332 if (tree->opval.op == BLOCK) {
4333 symbol *decls = tree->values.sym;
4334 fprintf(outfile,"{\n");
4336 INDENT(indent+4,outfile);
4337 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4338 printTypeChain(decls->type,outfile);
4339 fprintf(outfile,")\n");
4341 decls = decls->next;
4343 ast_print(tree->right,outfile,indent+4);
4344 fprintf(outfile,"}\n");
4347 if (tree->opval.op == NULLOP) {
4348 fprintf(outfile,"\n");
4349 ast_print(tree->left,outfile,indent);
4350 fprintf(outfile,"\n");
4351 ast_print(tree->right,outfile,indent);
4354 INDENT(indent,outfile);
4356 /*------------------------------------------------------------------*/
4357 /*----------------------------*/
4358 /* leaf has been reached */
4359 /*----------------------------*/
4360 /* if this is of type value */
4361 /* just get the type */
4362 if (tree->type == EX_VALUE) {
4364 if (IS_LITERAL (tree->opval.val->etype)) {
4365 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4366 (int) floatFromVal(tree->opval.val),
4367 (int) floatFromVal(tree->opval.val),
4368 floatFromVal(tree->opval.val));
4369 } else if (tree->opval.val->sym) {
4370 /* if the undefined flag is set then give error message */
4371 if (tree->opval.val->sym->undefined) {
4372 fprintf(outfile,"UNDEFINED SYMBOL ");
4374 fprintf(outfile,"SYMBOL ");
4376 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4379 fprintf(outfile," type (");
4380 printTypeChain(tree->ftype,outfile);
4381 fprintf(outfile,")\n");
4383 fprintf(outfile,"\n");
4388 /* if type link for the case of cast */
4389 if (tree->type == EX_LINK) {
4390 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4391 printTypeChain(tree->opval.lnk,outfile);
4392 fprintf(outfile,")\n");
4397 /* depending on type of operator do */
4399 switch (tree->opval.op) {
4400 /*------------------------------------------------------------------*/
4401 /*----------------------------*/
4403 /*----------------------------*/
4405 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4406 printTypeChain(tree->ftype,outfile);
4407 fprintf(outfile,")\n");
4408 ast_print(tree->left,outfile,indent+4);
4409 ast_print(tree->right,outfile,indent+4);
4412 /*------------------------------------------------------------------*/
4413 /*----------------------------*/
4415 /*----------------------------*/
4417 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4418 printTypeChain(tree->ftype,outfile);
4419 fprintf(outfile,")\n");
4420 ast_print(tree->left,outfile,indent+4);
4421 ast_print(tree->right,outfile,indent+4);
4424 /*------------------------------------------------------------------*/
4425 /*----------------------------*/
4426 /* struct/union pointer */
4427 /*----------------------------*/
4429 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4430 printTypeChain(tree->ftype,outfile);
4431 fprintf(outfile,")\n");
4432 ast_print(tree->left,outfile,indent+4);
4433 ast_print(tree->right,outfile,indent+4);
4436 /*------------------------------------------------------------------*/
4437 /*----------------------------*/
4438 /* ++/-- operation */
4439 /*----------------------------*/
4440 case INC_OP: /* incerement operator unary so left only */
4441 fprintf(outfile,"INC_OP (%p) type (",tree);
4442 printTypeChain(tree->ftype,outfile);
4443 fprintf(outfile,")\n");
4444 ast_print(tree->left,outfile,indent+4);
4448 fprintf(outfile,"DEC_OP (%p) type (",tree);
4449 printTypeChain(tree->ftype,outfile);
4450 fprintf(outfile,")\n");
4451 ast_print(tree->left,outfile,indent+4);
4454 /*------------------------------------------------------------------*/
4455 /*----------------------------*/
4457 /*----------------------------*/
4460 fprintf(outfile,"& (%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);
4466 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4467 printTypeChain(tree->ftype,outfile);
4468 fprintf(outfile,")\n");
4469 ast_print(tree->left,outfile,indent+4);
4470 ast_print(tree->right,outfile,indent+4);
4473 /*----------------------------*/
4475 /*----------------------------*/
4477 fprintf(outfile,"OR (%p) type (",tree);
4478 printTypeChain(tree->ftype,outfile);
4479 fprintf(outfile,")\n");
4480 ast_print(tree->left,outfile,indent+4);
4481 ast_print(tree->right,outfile,indent+4);
4483 /*------------------------------------------------------------------*/
4484 /*----------------------------*/
4486 /*----------------------------*/
4488 fprintf(outfile,"XOR (%p) type (",tree);
4489 printTypeChain(tree->ftype,outfile);
4490 fprintf(outfile,")\n");
4491 ast_print(tree->left,outfile,indent+4);
4492 ast_print(tree->right,outfile,indent+4);
4495 /*------------------------------------------------------------------*/
4496 /*----------------------------*/
4498 /*----------------------------*/
4500 fprintf(outfile,"DIV (%p) type (",tree);
4501 printTypeChain(tree->ftype,outfile);
4502 fprintf(outfile,")\n");
4503 ast_print(tree->left,outfile,indent+4);
4504 ast_print(tree->right,outfile,indent+4);
4506 /*------------------------------------------------------------------*/
4507 /*----------------------------*/
4509 /*----------------------------*/
4511 fprintf(outfile,"MOD (%p) type (",tree);
4512 printTypeChain(tree->ftype,outfile);
4513 fprintf(outfile,")\n");
4514 ast_print(tree->left,outfile,indent+4);
4515 ast_print(tree->right,outfile,indent+4);
4518 /*------------------------------------------------------------------*/
4519 /*----------------------------*/
4520 /* address dereference */
4521 /*----------------------------*/
4522 case '*': /* can be unary : if right is null then unary operation */
4524 fprintf(outfile,"DEREF (%p) type (",tree);
4525 printTypeChain(tree->ftype,outfile);
4526 fprintf(outfile,")\n");
4527 ast_print(tree->left,outfile,indent+4);
4530 /*------------------------------------------------------------------*/
4531 /*----------------------------*/
4532 /* multiplication */
4533 /*----------------------------*/
4534 fprintf(outfile,"MULT (%p) type (",tree);
4535 printTypeChain(tree->ftype,outfile);
4536 fprintf(outfile,")\n");
4537 ast_print(tree->left,outfile,indent+4);
4538 ast_print(tree->right,outfile,indent+4);
4542 /*------------------------------------------------------------------*/
4543 /*----------------------------*/
4544 /* unary '+' operator */
4545 /*----------------------------*/
4549 fprintf(outfile,"UPLUS (%p) type (",tree);
4550 printTypeChain(tree->ftype,outfile);
4551 fprintf(outfile,")\n");
4552 ast_print(tree->left,outfile,indent+4);
4554 /*------------------------------------------------------------------*/
4555 /*----------------------------*/
4557 /*----------------------------*/
4558 fprintf(outfile,"ADD (%p) type (",tree);
4559 printTypeChain(tree->ftype,outfile);
4560 fprintf(outfile,")\n");
4561 ast_print(tree->left,outfile,indent+4);
4562 ast_print(tree->right,outfile,indent+4);
4565 /*------------------------------------------------------------------*/
4566 /*----------------------------*/
4568 /*----------------------------*/
4569 case '-': /* can be unary */
4571 fprintf(outfile,"UMINUS (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+4);
4576 /*------------------------------------------------------------------*/
4577 /*----------------------------*/
4579 /*----------------------------*/
4580 fprintf(outfile,"SUB (%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 /*------------------------------------------------------------------*/
4588 /*----------------------------*/
4590 /*----------------------------*/
4592 fprintf(outfile,"COMPL (%p) type (",tree);
4593 printTypeChain(tree->ftype,outfile);
4594 fprintf(outfile,")\n");
4595 ast_print(tree->left,outfile,indent+4);
4597 /*------------------------------------------------------------------*/
4598 /*----------------------------*/
4600 /*----------------------------*/
4602 fprintf(outfile,"NOT (%p) type (",tree);
4603 printTypeChain(tree->ftype,outfile);
4604 fprintf(outfile,")\n");
4605 ast_print(tree->left,outfile,indent+4);
4607 /*------------------------------------------------------------------*/
4608 /*----------------------------*/
4610 /*----------------------------*/
4612 fprintf(outfile,"RRC (%p) type (",tree);
4613 printTypeChain(tree->ftype,outfile);
4614 fprintf(outfile,")\n");
4615 ast_print(tree->left,outfile,indent+4);
4619 fprintf(outfile,"RLC (%p) type (",tree);
4620 printTypeChain(tree->ftype,outfile);
4621 fprintf(outfile,")\n");
4622 ast_print(tree->left,outfile,indent+4);
4625 fprintf(outfile,"GETHBIT (%p) type (",tree);
4626 printTypeChain(tree->ftype,outfile);
4627 fprintf(outfile,")\n");
4628 ast_print(tree->left,outfile,indent+4);
4631 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+4);
4635 ast_print(tree->right,outfile,indent+4);
4638 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+4);
4642 ast_print(tree->right,outfile,indent+4);
4644 /*------------------------------------------------------------------*/
4645 /*----------------------------*/
4647 /*----------------------------*/
4648 case CAST: /* change the type */
4649 fprintf(outfile,"CAST (%p) type (",tree);
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->right,outfile,indent+4);
4656 fprintf(outfile,"ANDAND (%p) type (",tree);
4657 printTypeChain(tree->ftype,outfile);
4658 fprintf(outfile,")\n");
4659 ast_print(tree->left,outfile,indent+4);
4660 ast_print(tree->right,outfile,indent+4);
4663 fprintf(outfile,"OROR (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+4);
4667 ast_print(tree->right,outfile,indent+4);
4670 /*------------------------------------------------------------------*/
4671 /*----------------------------*/
4672 /* comparison operators */
4673 /*----------------------------*/
4675 fprintf(outfile,"GT(>) (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+4);
4679 ast_print(tree->right,outfile,indent+4);
4682 fprintf(outfile,"LT(<) (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+4);
4686 ast_print(tree->right,outfile,indent+4);
4689 fprintf(outfile,"LE(<=) (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+4);
4693 ast_print(tree->right,outfile,indent+4);
4696 fprintf(outfile,"GE(>=) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+4);
4700 ast_print(tree->right,outfile,indent+4);
4703 fprintf(outfile,"EQ(==) (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+4);
4707 ast_print(tree->right,outfile,indent+4);
4710 fprintf(outfile,"NE(!=) (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+4);
4714 ast_print(tree->right,outfile,indent+4);
4715 /*------------------------------------------------------------------*/
4716 /*----------------------------*/
4718 /*----------------------------*/
4719 case SIZEOF: /* evaluate wihout code generation */
4720 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4723 /*------------------------------------------------------------------*/
4724 /*----------------------------*/
4725 /* conditional operator '?' */
4726 /*----------------------------*/
4728 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4729 printTypeChain(tree->ftype,outfile);
4730 fprintf(outfile,")\n");
4731 ast_print(tree->left,outfile,indent+4);
4732 ast_print(tree->right,outfile,indent+4);
4735 fprintf(outfile,"COLON(:) (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+4);
4739 ast_print(tree->right,outfile,indent+4);
4742 /*------------------------------------------------------------------*/
4743 /*----------------------------*/
4744 /* assignment operators */
4745 /*----------------------------*/
4747 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4748 printTypeChain(tree->ftype,outfile);
4749 fprintf(outfile,")\n");
4750 ast_print(tree->left,outfile,indent+4);
4751 ast_print(tree->right,outfile,indent+4);
4754 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4755 printTypeChain(tree->ftype,outfile);
4756 fprintf(outfile,")\n");
4757 ast_print(tree->left,outfile,indent+4);
4758 ast_print(tree->right,outfile,indent+4);
4761 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4762 printTypeChain(tree->ftype,outfile);
4763 fprintf(outfile,")\n");
4764 ast_print(tree->left,outfile,indent+4);
4765 ast_print(tree->right,outfile,indent+4);
4768 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4769 printTypeChain(tree->ftype,outfile);
4770 fprintf(outfile,")\n");
4771 ast_print(tree->left,outfile,indent+4);
4772 ast_print(tree->right,outfile,indent+4);
4775 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4776 printTypeChain(tree->ftype,outfile);
4777 fprintf(outfile,")\n");
4778 ast_print(tree->left,outfile,indent+4);
4779 ast_print(tree->right,outfile,indent+4);
4782 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4783 printTypeChain(tree->ftype,outfile);
4784 fprintf(outfile,")\n");
4785 ast_print(tree->left,outfile,indent+4);
4786 ast_print(tree->right,outfile,indent+4);
4789 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4790 printTypeChain(tree->ftype,outfile);
4791 fprintf(outfile,")\n");
4792 ast_print(tree->left,outfile,indent+4);
4793 ast_print(tree->right,outfile,indent+4);
4795 /*------------------------------------------------------------------*/
4796 /*----------------------------*/
4798 /*----------------------------*/
4800 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4801 printTypeChain(tree->ftype,outfile);
4802 fprintf(outfile,")\n");
4803 ast_print(tree->left,outfile,indent+4);
4804 ast_print(tree->right,outfile,indent+4);
4806 /*------------------------------------------------------------------*/
4807 /*----------------------------*/
4809 /*----------------------------*/
4811 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4812 printTypeChain(tree->ftype,outfile);
4813 fprintf(outfile,")\n");
4814 ast_print(tree->left,outfile,indent+4);
4815 ast_print(tree->right,outfile,indent+4);
4817 /*------------------------------------------------------------------*/
4818 /*----------------------------*/
4819 /* straight assignemnt */
4820 /*----------------------------*/
4822 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4823 printTypeChain(tree->ftype,outfile);
4824 fprintf(outfile,")\n");
4825 ast_print(tree->left,outfile,indent+4);
4826 ast_print(tree->right,outfile,indent+4);
4828 /*------------------------------------------------------------------*/
4829 /*----------------------------*/
4830 /* comma operator */
4831 /*----------------------------*/
4833 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4834 printTypeChain(tree->ftype,outfile);
4835 fprintf(outfile,")\n");
4836 ast_print(tree->left,outfile,indent+4);
4837 ast_print(tree->right,outfile,indent+4);
4839 /*------------------------------------------------------------------*/
4840 /*----------------------------*/
4842 /*----------------------------*/
4845 fprintf(outfile,"CALL (%p) type (",tree);
4846 printTypeChain(tree->ftype,outfile);
4847 fprintf(outfile,")\n");
4848 ast_print(tree->left,outfile,indent+4);
4849 ast_print(tree->right,outfile,indent+4);
4852 fprintf(outfile,"PARM ");
4853 ast_print(tree->left,outfile,indent+4);
4854 if (tree->right && !IS_AST_PARAM(tree->right)) {
4855 fprintf(outfile,"PARM ");
4856 ast_print(tree->right,outfile,indent+4);
4859 /*------------------------------------------------------------------*/
4860 /*----------------------------*/
4861 /* return statement */
4862 /*----------------------------*/
4864 fprintf(outfile,"RETURN (%p) type (",tree);
4865 printTypeChain(tree->right->ftype,outfile);
4866 fprintf(outfile,")\n");
4867 ast_print(tree->right,outfile,indent+4);
4869 /*------------------------------------------------------------------*/
4870 /*----------------------------*/
4871 /* label statement */
4872 /*----------------------------*/
4874 fprintf(outfile,"LABEL (%p)",tree);
4875 ast_print(tree->left,outfile,indent+4);
4876 ast_print(tree->right,outfile,indent);
4878 /*------------------------------------------------------------------*/
4879 /*----------------------------*/
4880 /* switch statement */
4881 /*----------------------------*/
4885 fprintf(outfile,"SWITCH (%p) ",tree);
4886 ast_print(tree->left,outfile,0);
4887 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4888 INDENT(indent+4,outfile);
4889 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4890 (int) floatFromVal(val),
4891 tree->values.switchVals.swNum,
4892 (int) floatFromVal(val));
4894 ast_print(tree->right,outfile,indent);
4897 /*------------------------------------------------------------------*/
4898 /*----------------------------*/
4900 /*----------------------------*/
4902 ast_print(tree->left,outfile,indent);
4903 INDENT(indent,outfile);
4904 fprintf(outfile,"IF (%p) \n",tree);
4905 if (tree->trueLabel) {
4906 INDENT(indent,outfile);
4907 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4909 if (tree->falseLabel) {
4910 INDENT(indent,outfile);
4911 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4913 ast_print(tree->right,outfile,indent);
4915 /*------------------------------------------------------------------*/
4916 /*----------------------------*/
4918 /*----------------------------*/
4920 fprintf(outfile,"FOR (%p) \n",tree);
4921 if (AST_FOR( tree, initExpr)) {
4922 INDENT(indent+4,outfile);
4923 fprintf(outfile,"INIT EXPR ");
4924 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4926 if (AST_FOR( tree, condExpr)) {
4927 INDENT(indent+4,outfile);
4928 fprintf(outfile,"COND EXPR ");
4929 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4931 if (AST_FOR( tree, loopExpr)) {
4932 INDENT(indent+4,outfile);
4933 fprintf(outfile,"LOOP EXPR ");
4934 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4936 fprintf(outfile,"FOR LOOP BODY \n");
4937 ast_print(tree->left,outfile,indent+4);
4946 ast_print(t,stdout,1);