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
52 ast *createIval (ast *, sym_link *, initList *, ast *);
53 ast *createIvalCharPtr (ast *, sym_link *, ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
58 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
63 printTypeChain (tree->ftype, stdout);
68 /*-----------------------------------------------------------------*/
69 /* newAst - creates a fresh node for an expression tree */
70 /*-----------------------------------------------------------------*/
73 newAst (int type, void *op)
76 static int oldLineno = 0;
78 Safe_calloc (1, ex, sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
87 /* depending on the type */
91 ex->opval.val = (value *) op;
94 ex->opval.op = (long) op;
97 ex->opval.lnk = (sym_link *) op;
100 ex->opval.stmnt = (unsigned) op;
108 newAst_ (unsigned type)
111 static int oldLineno = 0;
113 ex = Safe_calloc (1, sizeof (ast));
116 ex->lineno = (noLineno ? oldLineno : yylineno);
117 ex->filename = currFname;
118 ex->level = NestLevel;
119 ex->block = currBlockno;
120 ex->initMode = inInitMode;
125 newAst_VALUE (value * val)
127 ast *ex = newAst_ (EX_VALUE);
133 newAst_OP (unsigned op)
135 ast *ex = newAst_ (EX_OP);
141 newAst_LINK (sym_link * val)
143 ast *ex = newAst_ (EX_LINK);
149 newAst_STMNT (unsigned val)
151 ast *ex = newAst_ (EX_STMNT);
152 ex->opval.stmnt = val;
156 /*-----------------------------------------------------------------*/
157 /* newNode - creates a new node */
158 /*-----------------------------------------------------------------*/
160 newNode (long op, ast * left, ast * right)
171 /*-----------------------------------------------------------------*/
172 /* newIfxNode - creates a new Ifx Node */
173 /*-----------------------------------------------------------------*/
175 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
179 /* if this is a literal then we already know the result */
180 if (condAst->etype && IS_LITERAL (condAst->etype))
182 /* then depending on the expression value */
183 if (floatFromVal (condAst->opval.val))
184 ifxNode = newNode (GOTO,
185 newAst_VALUE (symbolVal (trueLabel)),
188 ifxNode = newNode (GOTO,
189 newAst_VALUE (symbolVal (falseLabel)),
194 ifxNode = newNode (IFX, condAst, NULL);
195 ifxNode->trueLabel = trueLabel;
196 ifxNode->falseLabel = falseLabel;
202 /*-----------------------------------------------------------------*/
203 /* copyAstValues - copies value portion of ast if needed */
204 /*-----------------------------------------------------------------*/
206 copyAstValues (ast * dest, ast * src)
208 switch (src->opval.op)
211 dest->values.sym = copySymbolChain (src->values.sym);
215 dest->values.switchVals.swVals =
216 copyValue (src->values.switchVals.swVals);
217 dest->values.switchVals.swDefault =
218 src->values.switchVals.swDefault;
219 dest->values.switchVals.swNum =
220 src->values.switchVals.swNum;
224 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
225 strcpy (dest->values.inlineasm, src->values.inlineasm);
229 dest->values.constlist = copyLiteralList(src->values.constlist);
233 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
234 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
235 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
236 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
237 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
238 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
239 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
244 /*-----------------------------------------------------------------*/
245 /* copyAst - makes a copy of a given astession */
246 /*-----------------------------------------------------------------*/
255 dest = Safe_calloc (1, sizeof (ast));
257 dest->type = src->type;
258 dest->lineno = src->lineno;
259 dest->level = src->level;
260 dest->funcName = src->funcName;
261 dest->argSym = src->argSym;
263 /* if this is a leaf */
265 if (src->type == EX_VALUE)
267 dest->opval.val = copyValue (src->opval.val);
272 if (src->type == EX_LINK)
274 dest->opval.lnk = copyLinkChain (src->opval.lnk);
278 dest->opval.op = src->opval.op;
280 /* if this is a node that has special values */
281 copyAstValues (dest, src);
284 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
286 dest->trueLabel = copySymbol (src->trueLabel);
287 dest->falseLabel = copySymbol (src->falseLabel);
288 dest->left = copyAst (src->left);
289 dest->right = copyAst (src->right);
295 /*-----------------------------------------------------------------*/
296 /* hasSEFcalls - returns TRUE if tree has a function call */
297 /*-----------------------------------------------------------------*/
299 hasSEFcalls (ast * tree)
304 if (tree->type == EX_OP &&
305 (tree->opval.op == CALL ||
306 tree->opval.op == PCALL ||
307 tree->opval.op == '=' ||
308 tree->opval.op == INC_OP ||
309 tree->opval.op == DEC_OP))
312 return (hasSEFcalls (tree->left) |
313 hasSEFcalls (tree->right));
316 /*-----------------------------------------------------------------*/
317 /* isAstEqual - compares two asts & returns 1 if they are equal */
318 /*-----------------------------------------------------------------*/
320 isAstEqual (ast * t1, ast * t2)
329 if (t1->type != t2->type)
335 if (t1->opval.op != t2->opval.op)
337 return (isAstEqual (t1->left, t2->left) &&
338 isAstEqual (t1->right, t2->right));
342 if (t1->opval.val->sym)
344 if (!t2->opval.val->sym)
347 return isSymbolEqual (t1->opval.val->sym,
352 if (t2->opval.val->sym)
355 return (floatFromVal (t1->opval.val) ==
356 floatFromVal (t2->opval.val));
360 /* only compare these two types */
368 /*-----------------------------------------------------------------*/
369 /* resolveSymbols - resolve symbols from the symbol table */
370 /*-----------------------------------------------------------------*/
372 resolveSymbols (ast * tree)
374 /* walk the entire tree and check for values */
375 /* with symbols if we find one then replace */
376 /* symbol with that from the symbol table */
382 /* if not block & function */
383 if (tree->type == EX_OP &&
384 (tree->opval.op != FUNCTION &&
385 tree->opval.op != BLOCK &&
386 tree->opval.op != NULLOP))
388 filename = tree->filename;
389 lineno = tree->lineno;
392 /* make sure we resolve the true & false labels for ifx */
393 if (tree->type == EX_OP && tree->opval.op == IFX)
399 if ((csym = findSym (LabelTab, tree->trueLabel,
400 tree->trueLabel->name)))
401 tree->trueLabel = csym;
403 werror (E_LABEL_UNDEF, tree->trueLabel->name);
406 if (tree->falseLabel)
408 if ((csym = findSym (LabelTab,
410 tree->falseLabel->name)))
411 tree->falseLabel = csym;
413 werror (E_LABEL_UNDEF, tree->falseLabel->name);
418 /* if this is a label resolve it from the labelTab */
419 if (IS_AST_VALUE (tree) &&
420 tree->opval.val->sym &&
421 tree->opval.val->sym->islbl)
424 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
425 tree->opval.val->sym->name);
428 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
430 tree->opval.val->sym = csym;
432 goto resolveChildren;
435 /* do only for leafs */
436 if (IS_AST_VALUE (tree) &&
437 tree->opval.val->sym &&
438 !tree->opval.val->sym->implicit)
441 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
443 /* if found in the symbol table & they r not the same */
444 if (csym && tree->opval.val->sym != csym)
446 tree->opval.val->sym = csym;
447 tree->opval.val->type = csym->type;
448 tree->opval.val->etype = csym->etype;
451 /* if not found in the symbol table */
452 /* mark it as undefined assume it is */
453 /* an integer in data space */
454 if (!csym && !tree->opval.val->sym->implicit)
457 /* if this is a function name then */
458 /* mark it as returning an int */
461 tree->opval.val->sym->type = newLink ();
462 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
463 tree->opval.val->sym->type->next =
464 tree->opval.val->sym->etype = newIntLink ();
465 tree->opval.val->etype = tree->opval.val->etype;
466 tree->opval.val->type = tree->opval.val->sym->type;
467 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
468 allocVariables (tree->opval.val->sym);
472 tree->opval.val->sym->undefined = 1;
473 tree->opval.val->type =
474 tree->opval.val->etype = newIntLink ();
475 tree->opval.val->sym->type =
476 tree->opval.val->sym->etype = newIntLink ();
482 resolveSymbols (tree->left);
483 resolveSymbols (tree->right);
488 /*-----------------------------------------------------------------*/
489 /* setAstLineno - walks a ast tree & sets the line number */
490 /*-----------------------------------------------------------------*/
492 setAstLineno (ast * tree, int lineno)
497 tree->lineno = lineno;
498 setAstLineno (tree->left, lineno);
499 setAstLineno (tree->right, lineno);
504 /* this functions seems to be superfluous?! kmh */
506 /*-----------------------------------------------------------------*/
507 /* resolveFromTable - will return the symbal table value */
508 /*-----------------------------------------------------------------*/
510 resolveFromTable (value * val)
517 csym = findSymWithLevel (SymbolTab, val->sym);
519 /* if found in the symbol table & they r not the same */
520 if (csym && val->sym != csym &&
521 csym->level == val->sym->level &&
527 val->type = csym->type;
528 val->etype = csym->etype;
535 /*-----------------------------------------------------------------*/
536 /* funcOfType :- function of type with name */
537 /*-----------------------------------------------------------------*/
539 funcOfType (char *name, sym_link * type, sym_link * argType,
543 /* create the symbol */
544 sym = newSymbol (name, 0);
546 /* if arguments required */
551 args = sym->args = newValue ();
555 args->type = copyLinkChain (argType);
556 args->etype = getSpec (args->type);
559 args = args->next = newValue ();
563 /* setup return value */
564 sym->type = newLink ();
565 DCL_TYPE (sym->type) = FUNCTION;
566 sym->type->next = copyLinkChain (type);
567 sym->etype = getSpec (sym->type);
568 SPEC_RENT (sym->etype) = rent;
573 allocVariables (sym);
578 /*-----------------------------------------------------------------*/
579 /* reverseParms - will reverse a parameter tree */
580 /*-----------------------------------------------------------------*/
582 reverseParms (ast * ptree)
588 /* top down if we find a nonParm tree then quit */
589 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
592 ptree->left = ptree->right;
593 ptree->right = ttree;
594 reverseParms (ptree->left);
595 reverseParms (ptree->right);
601 /*-----------------------------------------------------------------*/
602 /* processParms - makes sure the parameters are okay and do some */
603 /* processing with them */
604 /*-----------------------------------------------------------------*/
606 processParms (ast * func,
612 sym_link *fetype = func->etype;
614 /* if none of them exist */
615 if (!defParm && !actParm)
619 if (getenv("DEBUG_SANITY")) {
620 fprintf (stderr, "addSym: %s ", defParm->name);
622 /* make sure the type is complete and sane */
623 checkTypeSanity(defParm->etype, defParm->name);
626 /* if the function is being called via a pointer & */
627 /* it has not been defined a reentrant then we cannot */
628 /* have parameters */
629 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
631 werror (W_NONRENT_ARGS);
635 /* if defined parameters ended but actual parameters */
636 /* exist and this is not defined as a variable arg */
637 /* also check if statckAuto option is specified */
638 if ((!defParm) && actParm && (!func->hasVargs) &&
639 !options.stackAuto && !IS_RENT (fetype))
641 werror (E_TOO_MANY_PARMS);
645 /* if defined parameters present but no actual parameters */
646 if (defParm && !actParm)
648 werror (E_TOO_FEW_PARMS);
652 /* If this is a varargs function... */
653 if (!defParm && actParm && func->hasVargs)
658 if (IS_CAST_OP (actParm)
659 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
661 /* Parameter was explicitly typecast; don't touch it. */
665 /* The ternary ('?') operator is weird: the ftype of the
666 * operator is the type of the condition, but it will return a
667 * (possibly) different type.
669 if (IS_TERNARY_OP(actParm))
671 assert(IS_COLON_OP(actParm->right));
672 assert(actParm->right->left);
673 ftype = actParm->right->left->ftype;
677 ftype = actParm->ftype;
680 /* If it's a small integer, upcast to int. */
681 if (IS_INTEGRAL (ftype)
682 && (getSize (ftype) < (unsigned) INTSIZE))
684 newType = newAst_LINK(INTTYPE);
687 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
689 newType = newAst_LINK (copyLinkChain(ftype));
690 DCL_TYPE (newType->opval.lnk) = GPOINTER;
693 if (IS_AGGREGATE (ftype))
695 newType = newAst_LINK (copyLinkChain (ftype));
696 DCL_TYPE (newType->opval.lnk) = GPOINTER;
700 /* cast required; change this op to a cast. */
701 ast *parmCopy = resolveSymbols (copyAst (actParm));
703 actParm->type = EX_OP;
704 actParm->opval.op = CAST;
705 actParm->left = newType;
706 actParm->right = parmCopy;
707 decorateType (actParm);
709 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
711 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
712 processParms (func, NULL, actParm->right, parmNumber, rightmost));
717 /* if defined parameters ended but actual has not & */
719 if (!defParm && actParm &&
720 (options.stackAuto || IS_RENT (fetype)))
723 resolveSymbols (actParm);
724 /* if this is a PARAM node then match left & right */
725 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
727 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
728 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
732 /* If we have found a value node by following only right-hand links,
733 * then we know that there are no more values after us.
735 * Therefore, if there are more defined parameters, the caller didn't
738 if (rightmost && defParm->next)
740 werror (E_TOO_FEW_PARMS);
746 /* the parameter type must be at least castable */
747 if (compareType (defParm->type, actParm->ftype) == 0) {
748 werror (E_INCOMPAT_TYPES);
749 fprintf (stderr, "type --> '");
750 printTypeChain (actParm->ftype, stderr);
751 fprintf (stderr, "' ");
752 fprintf (stderr, "assigned to type --> '");
753 printTypeChain (defParm->type, stderr);
754 fprintf (stderr, "'\n");
757 /* if the parameter is castable then add the cast */
758 if (compareType (defParm->type, actParm->ftype) < 0)
760 ast *pTree = resolveSymbols (copyAst (actParm));
762 /* now change the current one to a cast */
763 actParm->type = EX_OP;
764 actParm->opval.op = CAST;
765 actParm->left = newAst_LINK (defParm->type);
766 actParm->right = pTree;
767 actParm->etype = defParm->etype;
768 actParm->ftype = defParm->type;
771 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
773 actParm->argSym = defParm->sym;
774 /* make a copy and change the regparm type to the defined parm */
775 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
776 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
780 /*-----------------------------------------------------------------*/
781 /* createIvalType - generates ival for basic types */
782 /*-----------------------------------------------------------------*/
784 createIvalType (ast * sym, sym_link * type, initList * ilist)
788 /* if initList is deep */
789 if (ilist->type == INIT_DEEP)
790 ilist = ilist->init.deep;
792 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
793 return decorateType (newNode ('=', sym, iExpr));
796 /*-----------------------------------------------------------------*/
797 /* createIvalStruct - generates initial value for structures */
798 /*-----------------------------------------------------------------*/
800 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
806 sflds = SPEC_STRUCT (type)->fields;
807 if (ilist->type != INIT_DEEP)
809 werror (E_INIT_STRUCT, "");
813 iloop = ilist->init.deep;
815 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
819 /* if we have come to end */
823 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
824 lAst = decorateType (resolveSymbols (lAst));
825 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
831 /*-----------------------------------------------------------------*/
832 /* createIvalArray - generates code for array initialization */
833 /*-----------------------------------------------------------------*/
835 createIvalArray (ast * sym, sym_link * type, initList * ilist)
839 int lcnt = 0, size = 0;
840 literalList *literalL;
842 /* take care of the special case */
843 /* array of characters can be init */
845 if (IS_CHAR (type->next))
846 if ((rast = createIvalCharPtr (sym,
848 decorateType (resolveSymbols (list2expr (ilist))))))
850 return decorateType (resolveSymbols (rast));
852 /* not the special case */
853 if (ilist->type != INIT_DEEP)
855 werror (E_INIT_STRUCT, "");
859 iloop = ilist->init.deep;
860 lcnt = DCL_ELEM (type);
862 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
866 aSym = decorateType (resolveSymbols(sym));
868 rast = newNode(ARRAYINIT, aSym, NULL);
869 rast->values.constlist = literalL;
871 // Make sure size is set to length of initializer list.
878 if (lcnt && size > lcnt)
880 // Array size was specified, and we have more initializers than needed.
881 char *name=sym->opval.val->sym->name;
882 int lineno=sym->opval.val->sym->lineDef;
884 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
893 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
894 aSym = decorateType (resolveSymbols (aSym));
895 rast = createIval (aSym, type->next, iloop, rast);
896 iloop = (iloop ? iloop->next : NULL);
902 /* no of elements given and we */
903 /* have generated for all of them */
906 // there has to be a better way
907 char *name=sym->opval.val->sym->name;
908 int lineno=sym->opval.val->sym->lineDef;
909 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
916 /* if we have not been given a size */
917 if (!DCL_ELEM (type))
919 DCL_ELEM (type) = size;
922 return decorateType (resolveSymbols (rast));
926 /*-----------------------------------------------------------------*/
927 /* createIvalCharPtr - generates initial values for char pointers */
928 /*-----------------------------------------------------------------*/
930 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
934 /* if this is a pointer & right is a literal array then */
935 /* just assignment will do */
936 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
937 SPEC_SCLS (iexpr->etype) == S_CODE)
938 && IS_ARRAY (iexpr->ftype)))
939 return newNode ('=', sym, iexpr);
941 /* left side is an array so we have to assign each */
943 if ((IS_LITERAL (iexpr->etype) ||
944 SPEC_SCLS (iexpr->etype) == S_CODE)
945 && IS_ARRAY (iexpr->ftype))
947 /* for each character generate an assignment */
948 /* to the array element */
949 char *s = SPEC_CVAL (iexpr->etype).v_char;
954 rast = newNode (NULLOP,
958 newAst_VALUE (valueFromLit ((float) i))),
959 newAst_VALUE (valueFromLit (*s))));
963 rast = newNode (NULLOP,
967 newAst_VALUE (valueFromLit ((float) i))),
968 newAst_VALUE (valueFromLit (*s))));
969 return decorateType (resolveSymbols (rast));
975 /*-----------------------------------------------------------------*/
976 /* createIvalPtr - generates initial value for pointers */
977 /*-----------------------------------------------------------------*/
979 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
985 if (ilist->type == INIT_DEEP)
986 ilist = ilist->init.deep;
988 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
990 /* if character pointer */
991 if (IS_CHAR (type->next))
992 if ((rast = createIvalCharPtr (sym, type, iexpr)))
995 return newNode ('=', sym, iexpr);
998 /*-----------------------------------------------------------------*/
999 /* createIval - generates code for initial value */
1000 /*-----------------------------------------------------------------*/
1002 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1009 /* if structure then */
1010 if (IS_STRUCT (type))
1011 rast = createIvalStruct (sym, type, ilist);
1013 /* if this is a pointer */
1015 rast = createIvalPtr (sym, type, ilist);
1017 /* if this is an array */
1018 if (IS_ARRAY (type))
1019 rast = createIvalArray (sym, type, ilist);
1021 /* if type is SPECIFIER */
1023 rast = createIvalType (sym, type, ilist);
1026 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1028 return decorateType (resolveSymbols (rast));
1031 /*-----------------------------------------------------------------*/
1032 /* initAggregates - initialises aggregate variables with initv */
1033 /*-----------------------------------------------------------------*/
1035 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1037 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1041 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1043 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1044 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1045 "with -mmcs51 and --model-large");
1049 if (SPEC_OCLS(sym->etype)==xdata &&
1050 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1053 newSym=copySymbol (sym);
1054 SPEC_OCLS(newSym->etype)=code;
1055 sprintf (newSym->name, "%s_init__", sym->name);
1056 sprintf (newSym->rname,"%s_init__", sym->rname);
1057 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1059 // emit it in the static segment
1060 addSet(&statsg->syms, newSym);
1062 // now memcpy() the entire array from cseg
1063 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1064 newAst_VALUE (symbolVal (sym)),
1065 newAst_VALUE (symbolVal (newSym)));
1066 return decorateType(resolveSymbols(ast));
1070 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1073 /*-----------------------------------------------------------------*/
1074 /* gatherAutoInit - creates assignment expressions for initial */
1076 /*-----------------------------------------------------------------*/
1078 gatherAutoInit (symbol * autoChain)
1085 for (sym = autoChain; sym; sym = sym->next)
1088 /* resolve the symbols in the ival */
1090 resolveIvalSym (sym->ival);
1092 /* if this is a static variable & has an */
1093 /* initial value the code needs to be lifted */
1094 /* here to the main portion since they can be */
1095 /* initialised only once at the start */
1096 if (IS_STATIC (sym->etype) && sym->ival &&
1097 SPEC_SCLS (sym->etype) != S_CODE)
1101 // this can only be a constant
1102 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1103 werror (E_CONST_EXPECTED);
1106 /* insert the symbol into the symbol table */
1107 /* with level = 0 & name = rname */
1108 newSym = copySymbol (sym);
1109 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1111 /* now lift the code to main */
1112 if (IS_AGGREGATE (sym->type))
1113 work = initAggregates (sym, sym->ival, NULL);
1115 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1116 list2expr (sym->ival));
1118 setAstLineno (work, sym->lineDef);
1122 staticAutos = newNode (NULLOP, staticAutos, work);
1129 /* if there is an initial value */
1130 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1132 if (IS_AGGREGATE (sym->type))
1133 work = initAggregates (sym, sym->ival, NULL);
1135 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1136 list2expr (sym->ival));
1138 setAstLineno (work, sym->lineDef);
1141 init = newNode (NULLOP, init, work);
1150 /*-----------------------------------------------------------------*/
1151 /* stringToSymbol - creates a symbol from a literal string */
1152 /*-----------------------------------------------------------------*/
1154 stringToSymbol (value * val)
1156 char name[SDCC_NAME_MAX + 1];
1157 static int charLbl = 0;
1160 sprintf (name, "_str_%d", charLbl++);
1161 sym = newSymbol (name, 0); /* make it @ level 0 */
1162 strcpy (sym->rname, name);
1164 /* copy the type from the value passed */
1165 sym->type = copyLinkChain (val->type);
1166 sym->etype = getSpec (sym->type);
1167 /* change to storage class & output class */
1168 SPEC_SCLS (sym->etype) = S_CODE;
1169 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1170 SPEC_STAT (sym->etype) = 1;
1171 /* make the level & block = 0 */
1172 sym->block = sym->level = 0;
1174 /* create an ival */
1175 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1180 allocVariables (sym);
1183 return symbolVal (sym);
1187 /*-----------------------------------------------------------------*/
1188 /* processBlockVars - will go thru the ast looking for block if */
1189 /* a block is found then will allocate the syms */
1190 /* will also gather the auto inits present */
1191 /*-----------------------------------------------------------------*/
1193 processBlockVars (ast * tree, int *stack, int action)
1198 /* if this is a block */
1199 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1203 if (action == ALLOCATE)
1205 *stack += allocVariables (tree->values.sym);
1206 autoInit = gatherAutoInit (tree->values.sym);
1208 /* if there are auto inits then do them */
1210 tree->left = newNode (NULLOP, autoInit, tree->left);
1212 else /* action is deallocate */
1213 deallocLocal (tree->values.sym);
1216 processBlockVars (tree->left, stack, action);
1217 processBlockVars (tree->right, stack, action);
1221 /*-----------------------------------------------------------------*/
1222 /* constExprValue - returns the value of a constant expression */
1223 /* or NULL if it is not a constant expression */
1224 /*-----------------------------------------------------------------*/
1226 constExprValue (ast * cexpr, int check)
1228 cexpr = decorateType (resolveSymbols (cexpr));
1230 /* if this is not a constant then */
1231 if (!IS_LITERAL (cexpr->ftype))
1233 /* then check if this is a literal array
1235 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1236 SPEC_CVAL (cexpr->etype).v_char &&
1237 IS_ARRAY (cexpr->ftype))
1239 value *val = valFromType (cexpr->ftype);
1240 SPEC_SCLS (val->etype) = S_LITERAL;
1241 val->sym = cexpr->opval.val->sym;
1242 val->sym->type = copyLinkChain (cexpr->ftype);
1243 val->sym->etype = getSpec (val->sym->type);
1244 strcpy (val->name, cexpr->opval.val->sym->rname);
1248 /* if we are casting a literal value then */
1249 if (IS_AST_OP (cexpr) &&
1250 cexpr->opval.op == CAST &&
1251 IS_LITERAL (cexpr->left->ftype))
1252 return valCastLiteral (cexpr->ftype,
1253 floatFromVal (cexpr->left->opval.val));
1255 if (IS_AST_VALUE (cexpr))
1256 return cexpr->opval.val;
1259 werror (E_CONST_EXPECTED, "found expression");
1264 /* return the value */
1265 return cexpr->opval.val;
1269 /*-----------------------------------------------------------------*/
1270 /* isLabelInAst - will return true if a given label is found */
1271 /*-----------------------------------------------------------------*/
1273 isLabelInAst (symbol * label, ast * tree)
1275 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1278 if (IS_AST_OP (tree) &&
1279 tree->opval.op == LABEL &&
1280 isSymbolEqual (AST_SYMBOL (tree->left), label))
1283 return isLabelInAst (label, tree->right) &&
1284 isLabelInAst (label, tree->left);
1288 /*-----------------------------------------------------------------*/
1289 /* isLoopCountable - return true if the loop count can be determi- */
1290 /* -ned at compile time . */
1291 /*-----------------------------------------------------------------*/
1293 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1294 symbol ** sym, ast ** init, ast ** end)
1297 /* the loop is considered countable if the following
1298 conditions are true :-
1300 a) initExpr :- <sym> = <const>
1301 b) condExpr :- <sym> < <const1>
1302 c) loopExpr :- <sym> ++
1305 /* first check the initExpr */
1306 if (IS_AST_OP (initExpr) &&
1307 initExpr->opval.op == '=' && /* is assignment */
1308 IS_AST_SYM_VALUE (initExpr->left))
1309 { /* left is a symbol */
1311 *sym = AST_SYMBOL (initExpr->left);
1312 *init = initExpr->right;
1317 /* for now the symbol has to be of
1319 if (!IS_INTEGRAL ((*sym)->type))
1322 /* now check condExpr */
1323 if (IS_AST_OP (condExpr))
1326 switch (condExpr->opval.op)
1329 if (IS_AST_SYM_VALUE (condExpr->left) &&
1330 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1331 IS_AST_LIT_VALUE (condExpr->right))
1333 *end = condExpr->right;
1339 if (IS_AST_OP (condExpr->left) &&
1340 condExpr->left->opval.op == '>' &&
1341 IS_AST_LIT_VALUE (condExpr->left->right) &&
1342 IS_AST_SYM_VALUE (condExpr->left->left) &&
1343 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1346 *end = newNode ('+', condExpr->left->right,
1347 newAst_VALUE (constVal ("1")));
1358 /* check loop expression is of the form <sym>++ */
1359 if (!IS_AST_OP (loopExpr))
1362 /* check if <sym> ++ */
1363 if (loopExpr->opval.op == INC_OP)
1369 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1370 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1377 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1378 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1386 if (loopExpr->opval.op == ADD_ASSIGN)
1389 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1390 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1391 IS_AST_LIT_VALUE (loopExpr->right) &&
1392 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1400 /*-----------------------------------------------------------------*/
1401 /* astHasVolatile - returns true if ast contains any volatile */
1402 /*-----------------------------------------------------------------*/
1404 astHasVolatile (ast * tree)
1409 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1412 if (IS_AST_OP (tree))
1413 return astHasVolatile (tree->left) ||
1414 astHasVolatile (tree->right);
1419 /*-----------------------------------------------------------------*/
1420 /* astHasPointer - return true if the ast contains any ptr variable */
1421 /*-----------------------------------------------------------------*/
1423 astHasPointer (ast * tree)
1428 if (IS_AST_LINK (tree))
1431 /* if we hit an array expression then check
1432 only the left side */
1433 if (IS_AST_OP (tree) && tree->opval.op == '[')
1434 return astHasPointer (tree->left);
1436 if (IS_AST_VALUE (tree))
1437 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1439 return astHasPointer (tree->left) ||
1440 astHasPointer (tree->right);
1444 /*-----------------------------------------------------------------*/
1445 /* astHasSymbol - return true if the ast has the given symbol */
1446 /*-----------------------------------------------------------------*/
1448 astHasSymbol (ast * tree, symbol * sym)
1450 if (!tree || IS_AST_LINK (tree))
1453 if (IS_AST_VALUE (tree))
1455 if (IS_AST_SYM_VALUE (tree))
1456 return isSymbolEqual (AST_SYMBOL (tree), sym);
1461 return astHasSymbol (tree->left, sym) ||
1462 astHasSymbol (tree->right, sym);
1465 /*-----------------------------------------------------------------*/
1466 /* astHasDeref - return true if the ast has an indirect access */
1467 /*-----------------------------------------------------------------*/
1469 astHasDeref (ast * tree)
1471 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1474 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1476 return astHasDeref (tree->left) || astHasDeref (tree->right);
1479 /*-----------------------------------------------------------------*/
1480 /* isConformingBody - the loop body has to conform to a set of rules */
1481 /* for the loop to be considered reversible read on for rules */
1482 /*-----------------------------------------------------------------*/
1484 isConformingBody (ast * pbody, symbol * sym, ast * body)
1487 /* we are going to do a pre-order traversal of the
1488 tree && check for the following conditions. (essentially
1489 a set of very shallow tests )
1490 a) the sym passed does not participate in
1491 any arithmetic operation
1492 b) There are no function calls
1493 c) all jumps are within the body
1494 d) address of loop control variable not taken
1495 e) if an assignment has a pointer on the
1496 left hand side make sure right does not have
1497 loop control variable */
1499 /* if we reach the end or a leaf then true */
1500 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1504 /* if anything else is "volatile" */
1505 if (IS_VOLATILE (TETYPE (pbody)))
1508 /* we will walk the body in a pre-order traversal for
1510 switch (pbody->opval.op)
1512 /*------------------------------------------------------------------*/
1514 return isConformingBody (pbody->right, sym, body);
1516 /*------------------------------------------------------------------*/
1521 /*------------------------------------------------------------------*/
1522 case INC_OP: /* incerement operator unary so left only */
1525 /* sure we are not sym is not modified */
1527 IS_AST_SYM_VALUE (pbody->left) &&
1528 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1532 IS_AST_SYM_VALUE (pbody->right) &&
1533 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1538 /*------------------------------------------------------------------*/
1540 case '*': /* can be unary : if right is null then unary operation */
1545 /* if right is NULL then unary operation */
1546 /*------------------------------------------------------------------*/
1547 /*----------------------------*/
1549 /*----------------------------*/
1552 if (IS_AST_SYM_VALUE (pbody->left) &&
1553 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1556 return isConformingBody (pbody->left, sym, body);
1560 if (astHasSymbol (pbody->left, sym) ||
1561 astHasSymbol (pbody->right, sym))
1566 /*------------------------------------------------------------------*/
1574 if (IS_AST_SYM_VALUE (pbody->left) &&
1575 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1578 if (IS_AST_SYM_VALUE (pbody->right) &&
1579 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1582 return isConformingBody (pbody->left, sym, body) &&
1583 isConformingBody (pbody->right, sym, body);
1590 if (IS_AST_SYM_VALUE (pbody->left) &&
1591 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1593 return isConformingBody (pbody->left, sym, body);
1595 /*------------------------------------------------------------------*/
1607 case SIZEOF: /* evaluate wihout code generation */
1609 return isConformingBody (pbody->left, sym, body) &&
1610 isConformingBody (pbody->right, sym, body);
1612 /*------------------------------------------------------------------*/
1615 /* if left has a pointer & right has loop
1616 control variable then we cannot */
1617 if (astHasPointer (pbody->left) &&
1618 astHasSymbol (pbody->right, sym))
1620 if (astHasVolatile (pbody->left))
1623 if (IS_AST_SYM_VALUE (pbody->left) &&
1624 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1627 if (astHasVolatile (pbody->left))
1630 if (astHasDeref(pbody->right)) return FALSE;
1632 return isConformingBody (pbody->left, sym, body) &&
1633 isConformingBody (pbody->right, sym, body);
1644 assert ("Parser should not have generated this\n");
1646 /*------------------------------------------------------------------*/
1647 /*----------------------------*/
1648 /* comma operator */
1649 /*----------------------------*/
1651 return isConformingBody (pbody->left, sym, body) &&
1652 isConformingBody (pbody->right, sym, body);
1654 /*------------------------------------------------------------------*/
1655 /*----------------------------*/
1657 /*----------------------------*/
1661 /*------------------------------------------------------------------*/
1662 /*----------------------------*/
1663 /* return statement */
1664 /*----------------------------*/
1669 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1674 if (astHasSymbol (pbody->left, sym))
1681 return isConformingBody (pbody->left, sym, body) &&
1682 isConformingBody (pbody->right, sym, body);
1688 /*-----------------------------------------------------------------*/
1689 /* isLoopReversible - takes a for loop as input && returns true */
1690 /* if the for loop is reversible. If yes will set the value of */
1691 /* the loop control var & init value & termination value */
1692 /*-----------------------------------------------------------------*/
1694 isLoopReversible (ast * loop, symbol ** loopCntrl,
1695 ast ** init, ast ** end)
1697 /* if option says don't do it then don't */
1698 if (optimize.noLoopReverse)
1700 /* there are several tests to determine this */
1702 /* for loop has to be of the form
1703 for ( <sym> = <const1> ;
1704 [<sym> < <const2>] ;
1705 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1707 if (!isLoopCountable (AST_FOR (loop, initExpr),
1708 AST_FOR (loop, condExpr),
1709 AST_FOR (loop, loopExpr),
1710 loopCntrl, init, end))
1713 /* now do some serious checking on the body of the loop
1716 return isConformingBody (loop->left, *loopCntrl, loop->left);
1720 /*-----------------------------------------------------------------*/
1721 /* replLoopSym - replace the loop sym by loop sym -1 */
1722 /*-----------------------------------------------------------------*/
1724 replLoopSym (ast * body, symbol * sym)
1727 if (!body || IS_AST_LINK (body))
1730 if (IS_AST_SYM_VALUE (body))
1733 if (isSymbolEqual (AST_SYMBOL (body), sym))
1737 body->opval.op = '-';
1738 body->left = newAst_VALUE (symbolVal (sym));
1739 body->right = newAst_VALUE (constVal ("1"));
1747 replLoopSym (body->left, sym);
1748 replLoopSym (body->right, sym);
1752 /*-----------------------------------------------------------------*/
1753 /* reverseLoop - do the actual loop reversal */
1754 /*-----------------------------------------------------------------*/
1756 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1760 /* create the following tree
1765 if (sym) goto for_continue ;
1768 /* put it together piece by piece */
1769 rloop = newNode (NULLOP,
1770 createIf (newAst_VALUE (symbolVal (sym)),
1772 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1775 newAst_VALUE (symbolVal (sym)),
1778 replLoopSym (loop->left, sym);
1780 rloop = newNode (NULLOP,
1782 newAst_VALUE (symbolVal (sym)),
1783 newNode ('-', end, init)),
1784 createLabel (AST_FOR (loop, continueLabel),
1788 newNode (SUB_ASSIGN,
1789 newAst_VALUE (symbolVal (sym)),
1790 newAst_VALUE (constVal ("1"))),
1793 return decorateType (rloop);
1797 //#define DEMAND_INTEGER_PROMOTION
1799 #ifdef DEMAND_INTEGER_PROMOTION
1801 /*-----------------------------------------------------------------*/
1802 /* walk a tree looking for the leaves. Add a typecast to the given */
1803 /* type to each value leaf node. */
1804 /*-----------------------------------------------------------------*/
1806 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1808 if (!node || IS_CALLOP(node))
1810 /* WTF? We should never get here. */
1814 if (!node->left && !node->right)
1816 /* We're at a leaf; if it's a value, apply the typecast */
1817 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1819 *parentPtr = decorateType (newNode (CAST,
1820 newAst_LINK (copyLinkChain (type)),
1828 pushTypeCastToLeaves (type, node->left, &(node->left));
1832 pushTypeCastToLeaves (type, node->right, &(node->right));
1839 /*-----------------------------------------------------------------*/
1840 /* Given an assignment operation in a tree, determine if the LHS */
1841 /* (the result) has a different (integer) type than the RHS. */
1842 /* If so, walk the RHS and add a typecast to the type of the LHS */
1843 /* to all leaf nodes. */
1844 /*-----------------------------------------------------------------*/
1846 propAsgType (ast * tree)
1848 #ifdef DEMAND_INTEGER_PROMOTION
1849 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1851 /* Nothing to do here... */
1855 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1857 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1864 /*-----------------------------------------------------------------*/
1865 /* decorateType - compute type for this tree also does type cheking */
1866 /* this is done bottom up, since type have to flow upwards */
1867 /* it also does constant folding, and paramater checking */
1868 /*-----------------------------------------------------------------*/
1870 decorateType (ast * tree)
1878 /* if already has type then do nothing */
1879 if (tree->decorated)
1882 tree->decorated = 1;
1884 /* print the line */
1885 /* if not block & function */
1886 if (tree->type == EX_OP &&
1887 (tree->opval.op != FUNCTION &&
1888 tree->opval.op != BLOCK &&
1889 tree->opval.op != NULLOP))
1891 filename = tree->filename;
1892 lineno = tree->lineno;
1895 /* if any child is an error | this one is an error do nothing */
1896 if (tree->isError ||
1897 (tree->left && tree->left->isError) ||
1898 (tree->right && tree->right->isError))
1901 /*------------------------------------------------------------------*/
1902 /*----------------------------*/
1903 /* leaf has been reached */
1904 /*----------------------------*/
1905 /* if this is of type value */
1906 /* just get the type */
1907 if (tree->type == EX_VALUE)
1910 if (IS_LITERAL (tree->opval.val->etype))
1913 /* if this is a character array then declare it */
1914 if (IS_ARRAY (tree->opval.val->type))
1915 tree->opval.val = stringToSymbol (tree->opval.val);
1917 /* otherwise just copy the type information */
1918 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1919 if (funcInChain (tree->opval.val->type))
1921 tree->hasVargs = tree->opval.val->sym->hasVargs;
1922 tree->args = copyValueChain (tree->opval.val->sym->args);
1927 if (tree->opval.val->sym)
1929 /* if the undefined flag is set then give error message */
1930 if (tree->opval.val->sym->undefined)
1932 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1934 TTYPE (tree) = TETYPE (tree) =
1935 tree->opval.val->type = tree->opval.val->sym->type =
1936 tree->opval.val->etype = tree->opval.val->sym->etype =
1937 copyLinkChain (INTTYPE);
1942 /* if impilicit i.e. struct/union member then no type */
1943 if (tree->opval.val->sym->implicit)
1944 TTYPE (tree) = TETYPE (tree) = NULL;
1949 /* else copy the type */
1950 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1952 /* and mark it as referenced */
1953 tree->opval.val->sym->isref = 1;
1954 /* if this is of type function or function pointer */
1955 if (funcInChain (tree->opval.val->type))
1957 tree->hasVargs = tree->opval.val->sym->hasVargs;
1958 tree->args = copyValueChain (tree->opval.val->sym->args);
1968 /* if type link for the case of cast */
1969 if (tree->type == EX_LINK)
1971 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1978 dtl = decorateType (tree->left);
1979 dtr = decorateType (tree->right);
1981 /* this is to take care of situations
1982 when the tree gets rewritten */
1983 if (dtl != tree->left)
1985 if (dtr != tree->right)
1989 /* depending on type of operator do */
1991 switch (tree->opval.op)
1993 /*------------------------------------------------------------------*/
1994 /*----------------------------*/
1996 /*----------------------------*/
1999 /* determine which is the array & which the index */
2000 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2003 ast *tempTree = tree->left;
2004 tree->left = tree->right;
2005 tree->right = tempTree;
2008 /* first check if this is a array or a pointer */
2009 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2011 werror (E_NEED_ARRAY_PTR, "[]");
2012 goto errorTreeReturn;
2015 /* check if the type of the idx */
2016 if (!IS_INTEGRAL (RTYPE (tree)))
2018 werror (E_IDX_NOT_INT);
2019 goto errorTreeReturn;
2022 /* if the left is an rvalue then error */
2025 werror (E_LVALUE_REQUIRED, "array access");
2026 goto errorTreeReturn;
2029 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2030 if (IS_PTR(LTYPE(tree))) {
2031 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2035 /*------------------------------------------------------------------*/
2036 /*----------------------------*/
2038 /*----------------------------*/
2040 /* if this is not a structure */
2041 if (!IS_STRUCT (LTYPE (tree)))
2043 werror (E_STRUCT_UNION, ".");
2044 goto errorTreeReturn;
2046 TTYPE (tree) = structElemType (LTYPE (tree),
2047 (tree->right->type == EX_VALUE ?
2048 tree->right->opval.val : NULL), &tree->args);
2049 TETYPE (tree) = getSpec (TTYPE (tree));
2052 /*------------------------------------------------------------------*/
2053 /*----------------------------*/
2054 /* struct/union pointer */
2055 /*----------------------------*/
2057 /* if not pointer to a structure */
2058 if (!IS_PTR (LTYPE (tree)))
2060 werror (E_PTR_REQD);
2061 goto errorTreeReturn;
2064 if (!IS_STRUCT (LTYPE (tree)->next))
2066 werror (E_STRUCT_UNION, "->");
2067 goto errorTreeReturn;
2070 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2071 (tree->right->type == EX_VALUE ?
2072 tree->right->opval.val : NULL), &tree->args);
2073 TETYPE (tree) = getSpec (TTYPE (tree));
2076 /*------------------------------------------------------------------*/
2077 /*----------------------------*/
2078 /* ++/-- operation */
2079 /*----------------------------*/
2080 case INC_OP: /* incerement operator unary so left only */
2083 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2084 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2085 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2086 werror (E_CODE_WRITE, "++/--");
2095 /*------------------------------------------------------------------*/
2096 /*----------------------------*/
2098 /*----------------------------*/
2099 case '&': /* can be unary */
2100 /* if right is NULL then unary operation */
2101 if (tree->right) /* not an unary operation */
2104 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2106 werror (E_BITWISE_OP);
2107 werror (W_CONTINUE, "left & right types are ");
2108 printTypeChain (LTYPE (tree), stderr);
2109 fprintf (stderr, ",");
2110 printTypeChain (RTYPE (tree), stderr);
2111 fprintf (stderr, "\n");
2112 goto errorTreeReturn;
2115 /* if they are both literal */
2116 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2118 tree->type = EX_VALUE;
2119 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2120 valFromType (RETYPE (tree)), '&');
2122 tree->right = tree->left = NULL;
2123 TETYPE (tree) = tree->opval.val->etype;
2124 TTYPE (tree) = tree->opval.val->type;
2128 /* see if this is a GETHBIT operation if yes
2131 ast *otree = optimizeGetHbit (tree);
2134 return decorateType (otree);
2138 // we can't do this because of "(int & 0xff) << 3"
2140 /* if right or left is literal then result of that type */
2141 if (IS_LITERAL (RTYPE (tree)))
2144 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2145 TETYPE (tree) = getSpec (TTYPE (tree));
2146 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2150 if (IS_LITERAL (LTYPE (tree)))
2152 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2153 TETYPE (tree) = getSpec (TTYPE (tree));
2154 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2160 computeType (LTYPE (tree), RTYPE (tree));
2161 TETYPE (tree) = getSpec (TTYPE (tree));
2166 computeType (LTYPE (tree), RTYPE (tree));
2167 TETYPE (tree) = getSpec (TTYPE (tree));
2169 LRVAL (tree) = RRVAL (tree) = 1;
2173 /*------------------------------------------------------------------*/
2174 /*----------------------------*/
2176 /*----------------------------*/
2178 p->class = DECLARATOR;
2179 /* if bit field then error */
2180 if (IS_BITVAR (tree->left->etype))
2182 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2183 goto errorTreeReturn;
2186 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2188 werror (E_ILLEGAL_ADDR, "address of register variable");
2189 goto errorTreeReturn;
2192 if (IS_FUNC (LTYPE (tree)))
2194 werror (E_ILLEGAL_ADDR, "address of function");
2195 goto errorTreeReturn;
2200 werror (E_LVALUE_REQUIRED, "address of");
2201 goto errorTreeReturn;
2203 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2205 DCL_TYPE (p) = CPOINTER;
2206 DCL_PTR_CONST (p) = port->mem.code_ro;
2208 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2209 DCL_TYPE (p) = FPOINTER;
2210 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2211 DCL_TYPE (p) = PPOINTER;
2212 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2213 DCL_TYPE (p) = IPOINTER;
2214 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2215 DCL_TYPE (p) = EEPPOINTER;
2217 DCL_TYPE (p) = POINTER;
2219 if (IS_AST_SYM_VALUE (tree->left))
2221 AST_SYMBOL (tree->left)->addrtaken = 1;
2222 AST_SYMBOL (tree->left)->allocreq = 1;
2225 p->next = LTYPE (tree);
2227 TETYPE (tree) = getSpec (TTYPE (tree));
2228 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2229 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2234 /*------------------------------------------------------------------*/
2235 /*----------------------------*/
2237 /*----------------------------*/
2239 /* if the rewrite succeeds then don't go any furthur */
2241 ast *wtree = optimizeRRCRLC (tree);
2243 return decorateType (wtree);
2245 /*------------------------------------------------------------------*/
2246 /*----------------------------*/
2248 /*----------------------------*/
2250 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2252 werror (E_BITWISE_OP);
2253 werror (W_CONTINUE, "left & right types are ");
2254 printTypeChain (LTYPE (tree), stderr);
2255 fprintf (stderr, ",");
2256 printTypeChain (RTYPE (tree), stderr);
2257 fprintf (stderr, "\n");
2258 goto errorTreeReturn;
2261 /* if they are both literal then */
2262 /* rewrite the tree */
2263 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2265 tree->type = EX_VALUE;
2266 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2267 valFromType (RETYPE (tree)),
2269 tree->right = tree->left = NULL;
2270 TETYPE (tree) = tree->opval.val->etype;
2271 TTYPE (tree) = tree->opval.val->type;
2274 LRVAL (tree) = RRVAL (tree) = 1;
2275 TETYPE (tree) = getSpec (TTYPE (tree) =
2276 computeType (LTYPE (tree),
2279 /*------------------------------------------------------------------*/
2280 /*----------------------------*/
2282 /*----------------------------*/
2284 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2286 werror (E_INVALID_OP, "divide");
2287 goto errorTreeReturn;
2289 /* if they are both literal then */
2290 /* rewrite the tree */
2291 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2293 tree->type = EX_VALUE;
2294 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2295 valFromType (RETYPE (tree)));
2296 tree->right = tree->left = NULL;
2297 TETYPE (tree) = getSpec (TTYPE (tree) =
2298 tree->opval.val->type);
2301 LRVAL (tree) = RRVAL (tree) = 1;
2302 TETYPE (tree) = getSpec (TTYPE (tree) =
2303 computeType (LTYPE (tree),
2307 /*------------------------------------------------------------------*/
2308 /*----------------------------*/
2310 /*----------------------------*/
2312 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2314 werror (E_BITWISE_OP);
2315 werror (W_CONTINUE, "left & right types are ");
2316 printTypeChain (LTYPE (tree), stderr);
2317 fprintf (stderr, ",");
2318 printTypeChain (RTYPE (tree), stderr);
2319 fprintf (stderr, "\n");
2320 goto errorTreeReturn;
2322 /* if they are both literal then */
2323 /* rewrite the tree */
2324 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2326 tree->type = EX_VALUE;
2327 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2328 valFromType (RETYPE (tree)));
2329 tree->right = tree->left = NULL;
2330 TETYPE (tree) = getSpec (TTYPE (tree) =
2331 tree->opval.val->type);
2334 LRVAL (tree) = RRVAL (tree) = 1;
2335 TETYPE (tree) = getSpec (TTYPE (tree) =
2336 computeType (LTYPE (tree),
2340 /*------------------------------------------------------------------*/
2341 /*----------------------------*/
2342 /* address dereference */
2343 /*----------------------------*/
2344 case '*': /* can be unary : if right is null then unary operation */
2347 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2349 werror (E_PTR_REQD);
2350 goto errorTreeReturn;
2355 werror (E_LVALUE_REQUIRED, "pointer deref");
2356 goto errorTreeReturn;
2358 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2359 LTYPE (tree)->next : NULL);
2360 TETYPE (tree) = getSpec (TTYPE (tree));
2361 tree->args = tree->left->args;
2362 tree->hasVargs = tree->left->hasVargs;
2363 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2367 /*------------------------------------------------------------------*/
2368 /*----------------------------*/
2369 /* multiplication */
2370 /*----------------------------*/
2371 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2373 werror (E_INVALID_OP, "multiplication");
2374 goto errorTreeReturn;
2377 /* if they are both literal then */
2378 /* rewrite the tree */
2379 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2381 tree->type = EX_VALUE;
2382 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2383 valFromType (RETYPE (tree)));
2384 tree->right = tree->left = NULL;
2385 TETYPE (tree) = getSpec (TTYPE (tree) =
2386 tree->opval.val->type);
2390 /* if left is a literal exchange left & right */
2391 if (IS_LITERAL (LTYPE (tree)))
2393 ast *tTree = tree->left;
2394 tree->left = tree->right;
2395 tree->right = tTree;
2398 LRVAL (tree) = RRVAL (tree) = 1;
2399 /* promote result to int if left & right are char
2400 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2401 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2402 TETYPE (tree) = getSpec (TTYPE (tree) =
2403 computeType (LTYPE (tree),
2405 SPEC_NOUN(TETYPE(tree)) = V_INT;
2407 TETYPE (tree) = getSpec (TTYPE (tree) =
2408 computeType (LTYPE (tree),
2413 /*------------------------------------------------------------------*/
2414 /*----------------------------*/
2415 /* unary '+' operator */
2416 /*----------------------------*/
2421 if (!IS_INTEGRAL (LTYPE (tree)))
2423 werror (E_UNARY_OP, '+');
2424 goto errorTreeReturn;
2427 /* if left is a literal then do it */
2428 if (IS_LITERAL (LTYPE (tree)))
2430 tree->type = EX_VALUE;
2431 tree->opval.val = valFromType (LETYPE (tree));
2433 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2437 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2441 /*------------------------------------------------------------------*/
2442 /*----------------------------*/
2444 /*----------------------------*/
2446 /* this is not a unary operation */
2447 /* if both pointers then problem */
2448 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2449 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2451 werror (E_PTR_PLUS_PTR);
2452 goto errorTreeReturn;
2455 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2456 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2458 werror (E_PLUS_INVALID, "+");
2459 goto errorTreeReturn;
2462 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2463 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2465 werror (E_PLUS_INVALID, "+");
2466 goto errorTreeReturn;
2468 /* if they are both literal then */
2469 /* rewrite the tree */
2470 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2472 tree->type = EX_VALUE;
2473 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2474 valFromType (RETYPE (tree)));
2475 tree->right = tree->left = NULL;
2476 TETYPE (tree) = getSpec (TTYPE (tree) =
2477 tree->opval.val->type);
2481 /* if the right is a pointer or left is a literal
2482 xchange left & right */
2483 if (IS_ARRAY (RTYPE (tree)) ||
2484 IS_PTR (RTYPE (tree)) ||
2485 IS_LITERAL (LTYPE (tree)))
2487 ast *tTree = tree->left;
2488 tree->left = tree->right;
2489 tree->right = tTree;
2492 LRVAL (tree) = RRVAL (tree) = 1;
2493 /* if the left is a pointer */
2494 if (IS_PTR (LTYPE (tree)))
2495 TETYPE (tree) = getSpec (TTYPE (tree) =
2498 TETYPE (tree) = getSpec (TTYPE (tree) =
2499 computeType (LTYPE (tree),
2503 /*------------------------------------------------------------------*/
2504 /*----------------------------*/
2506 /*----------------------------*/
2507 case '-': /* can be unary */
2508 /* if right is null then unary */
2512 if (!IS_ARITHMETIC (LTYPE (tree)))
2514 werror (E_UNARY_OP, tree->opval.op);
2515 goto errorTreeReturn;
2518 /* if left is a literal then do it */
2519 if (IS_LITERAL (LTYPE (tree)))
2521 tree->type = EX_VALUE;
2522 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2524 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2525 SPEC_USIGN(TETYPE(tree)) = 0;
2529 TTYPE (tree) = LTYPE (tree);
2533 /*------------------------------------------------------------------*/
2534 /*----------------------------*/
2536 /*----------------------------*/
2538 if (!(IS_PTR (LTYPE (tree)) ||
2539 IS_ARRAY (LTYPE (tree)) ||
2540 IS_ARITHMETIC (LTYPE (tree))))
2542 werror (E_PLUS_INVALID, "-");
2543 goto errorTreeReturn;
2546 if (!(IS_PTR (RTYPE (tree)) ||
2547 IS_ARRAY (RTYPE (tree)) ||
2548 IS_ARITHMETIC (RTYPE (tree))))
2550 werror (E_PLUS_INVALID, "-");
2551 goto errorTreeReturn;
2554 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2555 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2556 IS_INTEGRAL (RTYPE (tree))))
2558 werror (E_PLUS_INVALID, "-");
2559 goto errorTreeReturn;
2562 /* if they are both literal then */
2563 /* rewrite the tree */
2564 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2566 tree->type = EX_VALUE;
2567 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2568 valFromType (RETYPE (tree)));
2569 tree->right = tree->left = NULL;
2570 TETYPE (tree) = getSpec (TTYPE (tree) =
2571 tree->opval.val->type);
2575 /* if the left & right are equal then zero */
2576 if (isAstEqual (tree->left, tree->right))
2578 tree->type = EX_VALUE;
2579 tree->left = tree->right = NULL;
2580 tree->opval.val = constVal ("0");
2581 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2585 /* if both of them are pointers or arrays then */
2586 /* the result is going to be an integer */
2587 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2588 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2589 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2591 /* if only the left is a pointer */
2592 /* then result is a pointer */
2593 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2594 TETYPE (tree) = getSpec (TTYPE (tree) =
2597 TETYPE (tree) = getSpec (TTYPE (tree) =
2598 computeType (LTYPE (tree),
2600 LRVAL (tree) = RRVAL (tree) = 1;
2603 /*------------------------------------------------------------------*/
2604 /*----------------------------*/
2606 /*----------------------------*/
2608 /* can be only integral type */
2609 if (!IS_INTEGRAL (LTYPE (tree)))
2611 werror (E_UNARY_OP, tree->opval.op);
2612 goto errorTreeReturn;
2615 /* if left is a literal then do it */
2616 if (IS_LITERAL (LTYPE (tree)))
2618 tree->type = EX_VALUE;
2619 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2621 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2625 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2628 /*------------------------------------------------------------------*/
2629 /*----------------------------*/
2631 /*----------------------------*/
2633 /* can be pointer */
2634 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2635 !IS_PTR (LTYPE (tree)) &&
2636 !IS_ARRAY (LTYPE (tree)))
2638 werror (E_UNARY_OP, tree->opval.op);
2639 goto errorTreeReturn;
2642 /* if left is a literal then do it */
2643 if (IS_LITERAL (LTYPE (tree)))
2645 tree->type = EX_VALUE;
2646 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2648 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2652 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2655 /*------------------------------------------------------------------*/
2656 /*----------------------------*/
2658 /*----------------------------*/
2661 TTYPE (tree) = LTYPE (tree);
2662 TETYPE (tree) = LETYPE (tree);
2666 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2671 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2673 werror (E_SHIFT_OP_INVALID);
2674 werror (W_CONTINUE, "left & right types are ");
2675 printTypeChain (LTYPE (tree), stderr);
2676 fprintf (stderr, ",");
2677 printTypeChain (RTYPE (tree), stderr);
2678 fprintf (stderr, "\n");
2679 goto errorTreeReturn;
2682 /* if they are both literal then */
2683 /* rewrite the tree */
2684 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2686 tree->type = EX_VALUE;
2687 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2688 valFromType (RETYPE (tree)),
2689 (tree->opval.op == LEFT_OP ? 1 : 0));
2690 tree->right = tree->left = NULL;
2691 TETYPE (tree) = getSpec (TTYPE (tree) =
2692 tree->opval.val->type);
2695 /* if only the right side is a literal & we are
2696 shifting more than size of the left operand then zero */
2697 if (IS_LITERAL (RTYPE (tree)) &&
2698 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2699 (getSize (LTYPE (tree)) * 8))
2701 werror (W_SHIFT_CHANGED,
2702 (tree->opval.op == LEFT_OP ? "left" : "right"));
2703 tree->type = EX_VALUE;
2704 tree->left = tree->right = NULL;
2705 tree->opval.val = constVal ("0");
2706 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2709 LRVAL (tree) = RRVAL (tree) = 1;
2710 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2712 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2716 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2720 /*------------------------------------------------------------------*/
2721 /*----------------------------*/
2723 /*----------------------------*/
2724 case CAST: /* change the type */
2725 /* cannot cast to an aggregate type */
2726 if (IS_AGGREGATE (LTYPE (tree)))
2728 werror (E_CAST_ILLEGAL);
2729 goto errorTreeReturn;
2732 /* make sure the type is complete and sane */
2733 checkTypeSanity(LETYPE(tree), "(cast)");
2736 /* if the right is a literal replace the tree */
2737 if (IS_LITERAL (RETYPE (tree))) {
2738 if (!IS_PTR (LTYPE (tree))) {
2739 tree->type = EX_VALUE;
2741 valCastLiteral (LTYPE (tree),
2742 floatFromVal (valFromType (RETYPE (tree))));
2745 TTYPE (tree) = tree->opval.val->type;
2746 tree->values.literalFromCast = 1;
2747 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2748 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2749 sym_link *rest = LTYPE(tree)->next;
2750 werror(W_LITERAL_GENERIC);
2751 TTYPE(tree) = newLink();
2752 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2753 TTYPE(tree)->next = rest;
2754 tree->left->opval.lnk = TTYPE(tree);
2757 TTYPE (tree) = LTYPE (tree);
2761 TTYPE (tree) = LTYPE (tree);
2765 /* if the right is a literal replace the tree */
2766 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2767 tree->type = EX_VALUE;
2769 valCastLiteral (LTYPE (tree),
2770 floatFromVal (valFromType (RETYPE (tree))));
2773 TTYPE (tree) = tree->opval.val->type;
2774 tree->values.literalFromCast = 1;
2776 TTYPE (tree) = LTYPE (tree);
2781 TETYPE (tree) = getSpec (TTYPE (tree));
2785 /*------------------------------------------------------------------*/
2786 /*----------------------------*/
2787 /* logical &&, || */
2788 /*----------------------------*/
2791 /* each must me arithmetic type or be a pointer */
2792 if (!IS_PTR (LTYPE (tree)) &&
2793 !IS_ARRAY (LTYPE (tree)) &&
2794 !IS_INTEGRAL (LTYPE (tree)))
2796 werror (E_COMPARE_OP);
2797 goto errorTreeReturn;
2800 if (!IS_PTR (RTYPE (tree)) &&
2801 !IS_ARRAY (RTYPE (tree)) &&
2802 !IS_INTEGRAL (RTYPE (tree)))
2804 werror (E_COMPARE_OP);
2805 goto errorTreeReturn;
2807 /* if they are both literal then */
2808 /* rewrite the tree */
2809 if (IS_LITERAL (RTYPE (tree)) &&
2810 IS_LITERAL (LTYPE (tree)))
2812 tree->type = EX_VALUE;
2813 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2814 valFromType (RETYPE (tree)),
2816 tree->right = tree->left = NULL;
2817 TETYPE (tree) = getSpec (TTYPE (tree) =
2818 tree->opval.val->type);
2821 LRVAL (tree) = RRVAL (tree) = 1;
2822 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2825 /*------------------------------------------------------------------*/
2826 /*----------------------------*/
2827 /* comparison operators */
2828 /*----------------------------*/
2836 ast *lt = optimizeCompare (tree);
2842 /* if they are pointers they must be castable */
2843 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2845 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2847 werror (E_COMPARE_OP);
2848 fprintf (stderr, "comparing type ");
2849 printTypeChain (LTYPE (tree), stderr);
2850 fprintf (stderr, "to type ");
2851 printTypeChain (RTYPE (tree), stderr);
2852 fprintf (stderr, "\n");
2853 goto errorTreeReturn;
2856 /* else they should be promotable to one another */
2859 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2860 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2862 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2864 werror (E_COMPARE_OP);
2865 fprintf (stderr, "comparing type ");
2866 printTypeChain (LTYPE (tree), stderr);
2867 fprintf (stderr, "to type ");
2868 printTypeChain (RTYPE (tree), stderr);
2869 fprintf (stderr, "\n");
2870 goto errorTreeReturn;
2874 /* if they are both literal then */
2875 /* rewrite the tree */
2876 if (IS_LITERAL (RTYPE (tree)) &&
2877 IS_LITERAL (LTYPE (tree)))
2879 tree->type = EX_VALUE;
2880 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2881 valFromType (RETYPE (tree)),
2883 tree->right = tree->left = NULL;
2884 TETYPE (tree) = getSpec (TTYPE (tree) =
2885 tree->opval.val->type);
2888 LRVAL (tree) = RRVAL (tree) = 1;
2889 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2892 /*------------------------------------------------------------------*/
2893 /*----------------------------*/
2895 /*----------------------------*/
2896 case SIZEOF: /* evaluate wihout code generation */
2897 /* change the type to a integer */
2898 tree->type = EX_VALUE;
2899 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2900 tree->opval.val = constVal (buffer);
2901 tree->right = tree->left = NULL;
2902 TETYPE (tree) = getSpec (TTYPE (tree) =
2903 tree->opval.val->type);
2906 /*------------------------------------------------------------------*/
2907 /*----------------------------*/
2908 /* conditional operator '?' */
2909 /*----------------------------*/
2911 /* the type is value of the colon operator (on the right) */
2912 assert(IS_COLON_OP(tree->right));
2913 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2914 TETYPE (tree) = getSpec (TTYPE (tree));
2918 /* if they don't match we have a problem */
2919 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2921 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2922 goto errorTreeReturn;
2925 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2926 TETYPE (tree) = getSpec (TTYPE (tree));
2930 /*------------------------------------------------------------------*/
2931 /*----------------------------*/
2932 /* assignment operators */
2933 /*----------------------------*/
2936 /* for these it must be both must be integral */
2937 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2938 !IS_ARITHMETIC (RTYPE (tree)))
2940 werror (E_OPS_INTEGRAL);
2941 goto errorTreeReturn;
2944 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2946 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2947 werror (E_CODE_WRITE, " ");
2951 werror (E_LVALUE_REQUIRED, "*= or /=");
2952 goto errorTreeReturn;
2965 /* for these it must be both must be integral */
2966 if (!IS_INTEGRAL (LTYPE (tree)) ||
2967 !IS_INTEGRAL (RTYPE (tree)))
2969 werror (E_OPS_INTEGRAL);
2970 goto errorTreeReturn;
2973 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2975 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2976 werror (E_CODE_WRITE, " ");
2980 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2981 goto errorTreeReturn;
2989 /*------------------------------------------------------------------*/
2990 /*----------------------------*/
2992 /*----------------------------*/
2994 if (!(IS_PTR (LTYPE (tree)) ||
2995 IS_ARITHMETIC (LTYPE (tree))))
2997 werror (E_PLUS_INVALID, "-=");
2998 goto errorTreeReturn;
3001 if (!(IS_PTR (RTYPE (tree)) ||
3002 IS_ARITHMETIC (RTYPE (tree))))
3004 werror (E_PLUS_INVALID, "-=");
3005 goto errorTreeReturn;
3008 TETYPE (tree) = getSpec (TTYPE (tree) =
3009 computeType (LTYPE (tree),
3012 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3013 werror (E_CODE_WRITE, " ");
3017 werror (E_LVALUE_REQUIRED, "-=");
3018 goto errorTreeReturn;
3026 /*------------------------------------------------------------------*/
3027 /*----------------------------*/
3029 /*----------------------------*/
3031 /* this is not a unary operation */
3032 /* if both pointers then problem */
3033 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3035 werror (E_PTR_PLUS_PTR);
3036 goto errorTreeReturn;
3039 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3041 werror (E_PLUS_INVALID, "+=");
3042 goto errorTreeReturn;
3045 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3047 werror (E_PLUS_INVALID, "+=");
3048 goto errorTreeReturn;
3051 TETYPE (tree) = getSpec (TTYPE (tree) =
3052 computeType (LTYPE (tree),
3055 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3056 werror (E_CODE_WRITE, " ");
3060 werror (E_LVALUE_REQUIRED, "+=");
3061 goto errorTreeReturn;
3064 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3065 tree->opval.op = '=';
3071 /*------------------------------------------------------------------*/
3072 /*----------------------------*/
3073 /* straight assignemnt */
3074 /*----------------------------*/
3076 /* cannot be an aggregate */
3077 if (IS_AGGREGATE (LTYPE (tree)))
3079 werror (E_AGGR_ASSIGN);
3080 goto errorTreeReturn;
3083 /* they should either match or be castable */
3084 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3086 werror (E_TYPE_MISMATCH, "assignment", " ");
3087 fprintf (stderr, "type --> '");
3088 printTypeChain (RTYPE (tree), stderr);
3089 fprintf (stderr, "' ");
3090 fprintf (stderr, "assigned to type --> '");
3091 printTypeChain (LTYPE (tree), stderr);
3092 fprintf (stderr, "'\n");
3093 goto errorTreeReturn;
3096 /* if the left side of the tree is of type void
3097 then report error */
3098 if (IS_VOID (LTYPE (tree)))
3100 werror (E_CAST_ZERO);
3101 fprintf (stderr, "type --> '");
3102 printTypeChain (RTYPE (tree), stderr);
3103 fprintf (stderr, "' ");
3104 fprintf (stderr, "assigned to type --> '");
3105 printTypeChain (LTYPE (tree), stderr);
3106 fprintf (stderr, "'\n");
3109 TETYPE (tree) = getSpec (TTYPE (tree) =
3113 if (!tree->initMode ) {
3114 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3115 werror (E_CODE_WRITE, " ");
3119 werror (E_LVALUE_REQUIRED, "=");
3120 goto errorTreeReturn;
3127 /*------------------------------------------------------------------*/
3128 /*----------------------------*/
3129 /* comma operator */
3130 /*----------------------------*/
3132 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3135 /*------------------------------------------------------------------*/
3136 /*----------------------------*/
3138 /*----------------------------*/
3142 if (processParms (tree->left,
3144 tree->right, &parmNumber, TRUE))
3145 goto errorTreeReturn;
3147 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3149 tree->left->args = reverseVal (tree->left->args);
3150 reverseParms (tree->right);
3153 tree->args = tree->left->args;
3154 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3157 /*------------------------------------------------------------------*/
3158 /*----------------------------*/
3159 /* return statement */
3160 /*----------------------------*/
3165 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3167 werror (W_RETURN_MISMATCH);
3168 goto errorTreeReturn;
3171 if (IS_VOID (currFunc->type->next)
3173 !IS_VOID (RTYPE (tree)))
3175 werror (E_FUNC_VOID);
3176 goto errorTreeReturn;
3179 /* if there is going to be a casing required then add it */
3180 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3182 #if 0 && defined DEMAND_INTEGER_PROMOTION
3183 if (IS_INTEGRAL (currFunc->type->next))
3185 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3191 decorateType (newNode (CAST,
3192 newAst_LINK (copyLinkChain (currFunc->type->next)),
3202 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3204 werror (E_VOID_FUNC, currFunc->name);
3205 goto errorTreeReturn;
3208 TTYPE (tree) = TETYPE (tree) = NULL;
3211 /*------------------------------------------------------------------*/
3212 /*----------------------------*/
3213 /* switch statement */
3214 /*----------------------------*/
3216 /* the switch value must be an integer */
3217 if (!IS_INTEGRAL (LTYPE (tree)))
3219 werror (E_SWITCH_NON_INTEGER);
3220 goto errorTreeReturn;
3223 TTYPE (tree) = TETYPE (tree) = NULL;
3226 /*------------------------------------------------------------------*/
3227 /*----------------------------*/
3229 /*----------------------------*/
3231 tree->left = backPatchLabels (tree->left,
3234 TTYPE (tree) = TETYPE (tree) = NULL;
3237 /*------------------------------------------------------------------*/
3238 /*----------------------------*/
3240 /*----------------------------*/
3243 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3244 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3245 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3247 /* if the for loop is reversible then
3248 reverse it otherwise do what we normally
3254 if (isLoopReversible (tree, &sym, &init, &end))
3255 return reverseLoop (tree, sym, init, end);
3257 return decorateType (createFor (AST_FOR (tree, trueLabel),
3258 AST_FOR (tree, continueLabel),
3259 AST_FOR (tree, falseLabel),
3260 AST_FOR (tree, condLabel),
3261 AST_FOR (tree, initExpr),
3262 AST_FOR (tree, condExpr),
3263 AST_FOR (tree, loopExpr),
3267 TTYPE (tree) = TETYPE (tree) = NULL;
3271 /* some error found this tree will be killed */
3273 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3274 tree->opval.op = NULLOP;
3280 /*-----------------------------------------------------------------*/
3281 /* sizeofOp - processes size of operation */
3282 /*-----------------------------------------------------------------*/
3284 sizeofOp (sym_link * type)
3288 /* make sure the type is complete and sane */
3289 checkTypeSanity(type, "(sizeof)");
3291 /* get the size and convert it to character */
3292 sprintf (buff, "%d", getSize (type));
3294 /* now convert into value */
3295 return constVal (buff);
3299 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3300 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3301 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3302 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3303 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3304 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3305 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3307 /*-----------------------------------------------------------------*/
3308 /* backPatchLabels - change and or not operators to flow control */
3309 /*-----------------------------------------------------------------*/
3311 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3317 if (!(IS_ANDORNOT (tree)))
3320 /* if this an and */
3323 static int localLbl = 0;
3326 sprintf (buffer, "_and_%d", localLbl++);
3327 localLabel = newSymbol (buffer, NestLevel);
3329 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3331 /* if left is already a IFX then just change the if true label in that */
3332 if (!IS_IFX (tree->left))
3333 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3335 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3336 /* right is a IFX then just join */
3337 if (IS_IFX (tree->right))
3338 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3340 tree->right = createLabel (localLabel, tree->right);
3341 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3343 return newNode (NULLOP, tree->left, tree->right);
3346 /* if this is an or operation */
3349 static int localLbl = 0;
3352 sprintf (buffer, "_or_%d", localLbl++);
3353 localLabel = newSymbol (buffer, NestLevel);
3355 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3357 /* if left is already a IFX then just change the if true label in that */
3358 if (!IS_IFX (tree->left))
3359 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3361 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3362 /* right is a IFX then just join */
3363 if (IS_IFX (tree->right))
3364 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3366 tree->right = createLabel (localLabel, tree->right);
3367 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3369 return newNode (NULLOP, tree->left, tree->right);
3375 int wasnot = IS_NOT (tree->left);
3376 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3378 /* if the left is already a IFX */
3379 if (!IS_IFX (tree->left))
3380 tree->left = newNode (IFX, tree->left, NULL);
3384 tree->left->trueLabel = trueLabel;
3385 tree->left->falseLabel = falseLabel;
3389 tree->left->trueLabel = falseLabel;
3390 tree->left->falseLabel = trueLabel;
3397 tree->trueLabel = trueLabel;
3398 tree->falseLabel = falseLabel;
3405 /*-----------------------------------------------------------------*/
3406 /* createBlock - create expression tree for block */
3407 /*-----------------------------------------------------------------*/
3409 createBlock (symbol * decl, ast * body)
3413 /* if the block has nothing */
3417 ex = newNode (BLOCK, NULL, body);
3418 ex->values.sym = decl;
3420 ex->right = ex->right;
3426 /*-----------------------------------------------------------------*/
3427 /* createLabel - creates the expression tree for labels */
3428 /*-----------------------------------------------------------------*/
3430 createLabel (symbol * label, ast * stmnt)
3433 char name[SDCC_NAME_MAX + 1];
3436 /* must create fresh symbol if the symbol name */
3437 /* exists in the symbol table, since there can */
3438 /* be a variable with the same name as the labl */
3439 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3440 (csym->level == label->level))
3441 label = newSymbol (label->name, label->level);
3443 /* change the name before putting it in add _ */
3444 sprintf (name, "%s", label->name);
3446 /* put the label in the LabelSymbol table */
3447 /* but first check if a label of the same */
3449 if ((csym = findSym (LabelTab, NULL, name)))
3450 werror (E_DUPLICATE_LABEL, label->name);
3452 addSym (LabelTab, label, name, label->level, 0, 0);
3455 label->key = labelKey++;
3456 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3462 /*-----------------------------------------------------------------*/
3463 /* createCase - generates the parsetree for a case statement */
3464 /*-----------------------------------------------------------------*/
3466 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3468 char caseLbl[SDCC_NAME_MAX + 1];
3472 /* if the switch statement does not exist */
3473 /* then case is out of context */
3476 werror (E_CASE_CONTEXT);
3480 caseVal = decorateType (resolveSymbols (caseVal));
3481 /* if not a constant then error */
3482 if (!IS_LITERAL (caseVal->ftype))
3484 werror (E_CASE_CONSTANT);
3488 /* if not a integer than error */
3489 if (!IS_INTEGRAL (caseVal->ftype))
3491 werror (E_CASE_NON_INTEGER);
3495 /* find the end of the switch values chain */
3496 if (!(val = swStat->values.switchVals.swVals))
3497 swStat->values.switchVals.swVals = caseVal->opval.val;
3500 /* also order the cases according to value */
3502 int cVal = (int) floatFromVal (caseVal->opval.val);
3503 while (val && (int) floatFromVal (val) < cVal)
3509 /* if we reached the end then */
3512 pval->next = caseVal->opval.val;
3516 /* we found a value greater than */
3517 /* the current value we must add this */
3518 /* before the value */
3519 caseVal->opval.val->next = val;
3521 /* if this was the first in chain */
3522 if (swStat->values.switchVals.swVals == val)
3523 swStat->values.switchVals.swVals =
3526 pval->next = caseVal->opval.val;
3531 /* create the case label */
3532 sprintf (caseLbl, "_case_%d_%d",
3533 swStat->values.switchVals.swNum,
3534 (int) floatFromVal (caseVal->opval.val));
3536 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3541 /*-----------------------------------------------------------------*/
3542 /* createDefault - creates the parse tree for the default statement */
3543 /*-----------------------------------------------------------------*/
3545 createDefault (ast * swStat, ast * stmnt)
3547 char defLbl[SDCC_NAME_MAX + 1];
3549 /* if the switch statement does not exist */
3550 /* then case is out of context */
3553 werror (E_CASE_CONTEXT);
3557 /* turn on the default flag */
3558 swStat->values.switchVals.swDefault = 1;
3560 /* create the label */
3561 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3562 return createLabel (newSymbol (defLbl, 0), stmnt);
3565 /*-----------------------------------------------------------------*/
3566 /* createIf - creates the parsetree for the if statement */
3567 /*-----------------------------------------------------------------*/
3569 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3571 static int Lblnum = 0;
3573 symbol *ifTrue, *ifFalse, *ifEnd;
3575 /* if neither exists */
3576 if (!elseBody && !ifBody)
3579 /* create the labels */
3580 sprintf (buffer, "_iffalse_%d", Lblnum);
3581 ifFalse = newSymbol (buffer, NestLevel);
3582 /* if no else body then end == false */
3587 sprintf (buffer, "_ifend_%d", Lblnum);
3588 ifEnd = newSymbol (buffer, NestLevel);
3591 sprintf (buffer, "_iftrue_%d", Lblnum);
3592 ifTrue = newSymbol (buffer, NestLevel);
3596 /* attach the ifTrue label to the top of it body */
3597 ifBody = createLabel (ifTrue, ifBody);
3598 /* attach a goto end to the ifBody if else is present */
3601 ifBody = newNode (NULLOP, ifBody,
3603 newAst_VALUE (symbolVal (ifEnd)),
3605 /* put the elseLabel on the else body */
3606 elseBody = createLabel (ifFalse, elseBody);
3607 /* out the end at the end of the body */
3608 elseBody = newNode (NULLOP,
3610 createLabel (ifEnd, NULL));
3614 ifBody = newNode (NULLOP, ifBody,
3615 createLabel (ifFalse, NULL));
3617 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3618 if (IS_IFX (condAst))
3621 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3623 return newNode (NULLOP, ifTree,
3624 newNode (NULLOP, ifBody, elseBody));
3628 /*-----------------------------------------------------------------*/
3629 /* createDo - creates parse tree for do */
3632 /* _docontinue_n: */
3633 /* condition_expression +-> trueLabel -> _dobody_n */
3635 /* +-> falseLabel-> _dobreak_n */
3637 /*-----------------------------------------------------------------*/
3639 createDo (symbol * trueLabel, symbol * continueLabel,
3640 symbol * falseLabel, ast * condAst, ast * doBody)
3645 /* if the body does not exist then it is simple */
3648 condAst = backPatchLabels (condAst, continueLabel, NULL);
3649 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3650 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3651 doTree->trueLabel = continueLabel;
3652 doTree->falseLabel = NULL;
3656 /* otherwise we have a body */
3657 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3659 /* attach the body label to the top */
3660 doBody = createLabel (trueLabel, doBody);
3661 /* attach the continue label to end of body */
3662 doBody = newNode (NULLOP, doBody,
3663 createLabel (continueLabel, NULL));
3665 /* now put the break label at the end */
3666 if (IS_IFX (condAst))
3669 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3671 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3673 /* putting it together */
3674 return newNode (NULLOP, doBody, doTree);
3677 /*-----------------------------------------------------------------*/
3678 /* createFor - creates parse tree for 'for' statement */
3681 /* condExpr +-> trueLabel -> _forbody_n */
3683 /* +-> falseLabel-> _forbreak_n */
3686 /* _forcontinue_n: */
3688 /* goto _forcond_n ; */
3690 /*-----------------------------------------------------------------*/
3692 createFor (symbol * trueLabel, symbol * continueLabel,
3693 symbol * falseLabel, symbol * condLabel,
3694 ast * initExpr, ast * condExpr, ast * loopExpr,
3699 /* if loopexpression not present then we can generate it */
3700 /* the same way as a while */
3702 return newNode (NULLOP, initExpr,
3703 createWhile (trueLabel, continueLabel,
3704 falseLabel, condExpr, forBody));
3705 /* vanilla for statement */
3706 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3708 if (condExpr && !IS_IFX (condExpr))
3709 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3712 /* attach condition label to condition */
3713 condExpr = createLabel (condLabel, condExpr);
3715 /* attach body label to body */
3716 forBody = createLabel (trueLabel, forBody);
3718 /* attach continue to forLoop expression & attach */
3719 /* goto the forcond @ and of loopExpression */
3720 loopExpr = createLabel (continueLabel,
3724 newAst_VALUE (symbolVal (condLabel)),
3726 /* now start putting them together */
3727 forTree = newNode (NULLOP, initExpr, condExpr);
3728 forTree = newNode (NULLOP, forTree, forBody);
3729 forTree = newNode (NULLOP, forTree, loopExpr);
3730 /* finally add the break label */
3731 forTree = newNode (NULLOP, forTree,
3732 createLabel (falseLabel, NULL));
3736 /*-----------------------------------------------------------------*/
3737 /* createWhile - creates parse tree for while statement */
3738 /* the while statement will be created as follows */
3740 /* _while_continue_n: */
3741 /* condition_expression +-> trueLabel -> _while_boby_n */
3743 /* +-> falseLabel -> _while_break_n */
3744 /* _while_body_n: */
3746 /* goto _while_continue_n */
3747 /* _while_break_n: */
3748 /*-----------------------------------------------------------------*/
3750 createWhile (symbol * trueLabel, symbol * continueLabel,
3751 symbol * falseLabel, ast * condExpr, ast * whileBody)
3755 /* put the continue label */
3756 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3757 condExpr = createLabel (continueLabel, condExpr);
3758 condExpr->lineno = 0;
3760 /* put the body label in front of the body */
3761 whileBody = createLabel (trueLabel, whileBody);
3762 whileBody->lineno = 0;
3763 /* put a jump to continue at the end of the body */
3764 /* and put break label at the end of the body */
3765 whileBody = newNode (NULLOP,
3768 newAst_VALUE (symbolVal (continueLabel)),
3769 createLabel (falseLabel, NULL)));
3771 /* put it all together */
3772 if (IS_IFX (condExpr))
3773 whileTree = condExpr;
3776 whileTree = newNode (IFX, condExpr, NULL);
3777 /* put the true & false labels in place */
3778 whileTree->trueLabel = trueLabel;
3779 whileTree->falseLabel = falseLabel;
3782 return newNode (NULLOP, whileTree, whileBody);
3785 /*-----------------------------------------------------------------*/
3786 /* optimizeGetHbit - get highest order bit of the expression */
3787 /*-----------------------------------------------------------------*/
3789 optimizeGetHbit (ast * tree)
3792 /* if this is not a bit and */
3793 if (!IS_BITAND (tree))
3796 /* will look for tree of the form
3797 ( expr >> ((sizeof expr) -1) ) & 1 */
3798 if (!IS_AST_LIT_VALUE (tree->right))
3801 if (AST_LIT_VALUE (tree->right) != 1)
3804 if (!IS_RIGHT_OP (tree->left))
3807 if (!IS_AST_LIT_VALUE (tree->left->right))
3810 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3811 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3814 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3818 /*-----------------------------------------------------------------*/
3819 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3820 /*-----------------------------------------------------------------*/
3822 optimizeRRCRLC (ast * root)
3824 /* will look for trees of the form
3825 (?expr << 1) | (?expr >> 7) or
3826 (?expr >> 7) | (?expr << 1) will make that
3827 into a RLC : operation ..
3829 (?expr >> 1) | (?expr << 7) or
3830 (?expr << 7) | (?expr >> 1) will make that
3831 into a RRC operation
3832 note : by 7 I mean (number of bits required to hold the
3834 /* if the root operations is not a | operation the not */
3835 if (!IS_BITOR (root))
3838 /* I have to think of a better way to match patterns this sucks */
3839 /* that aside let start looking for the first case : I use a the
3840 negative check a lot to improve the efficiency */
3841 /* (?expr << 1) | (?expr >> 7) */
3842 if (IS_LEFT_OP (root->left) &&
3843 IS_RIGHT_OP (root->right))
3846 if (!SPEC_USIGN (TETYPE (root->left->left)))
3849 if (!IS_AST_LIT_VALUE (root->left->right) ||
3850 !IS_AST_LIT_VALUE (root->right->right))
3853 /* make sure it is the same expression */
3854 if (!isAstEqual (root->left->left,
3858 if (AST_LIT_VALUE (root->left->right) != 1)
3861 if (AST_LIT_VALUE (root->right->right) !=
3862 (getSize (TTYPE (root->left->left)) * 8 - 1))
3865 /* whew got the first case : create the AST */
3866 return newNode (RLC, root->left->left, NULL);
3870 /* check for second case */
3871 /* (?expr >> 7) | (?expr << 1) */
3872 if (IS_LEFT_OP (root->right) &&
3873 IS_RIGHT_OP (root->left))
3876 if (!SPEC_USIGN (TETYPE (root->left->left)))
3879 if (!IS_AST_LIT_VALUE (root->left->right) ||
3880 !IS_AST_LIT_VALUE (root->right->right))
3883 /* make sure it is the same symbol */
3884 if (!isAstEqual (root->left->left,
3888 if (AST_LIT_VALUE (root->right->right) != 1)
3891 if (AST_LIT_VALUE (root->left->right) !=
3892 (getSize (TTYPE (root->left->left)) * 8 - 1))
3895 /* whew got the first case : create the AST */
3896 return newNode (RLC, root->left->left, NULL);
3901 /* third case for RRC */
3902 /* (?symbol >> 1) | (?symbol << 7) */
3903 if (IS_LEFT_OP (root->right) &&
3904 IS_RIGHT_OP (root->left))
3907 if (!SPEC_USIGN (TETYPE (root->left->left)))
3910 if (!IS_AST_LIT_VALUE (root->left->right) ||
3911 !IS_AST_LIT_VALUE (root->right->right))
3914 /* make sure it is the same symbol */
3915 if (!isAstEqual (root->left->left,
3919 if (AST_LIT_VALUE (root->left->right) != 1)
3922 if (AST_LIT_VALUE (root->right->right) !=
3923 (getSize (TTYPE (root->left->left)) * 8 - 1))
3926 /* whew got the first case : create the AST */
3927 return newNode (RRC, root->left->left, NULL);
3931 /* fourth and last case for now */
3932 /* (?symbol << 7) | (?symbol >> 1) */
3933 if (IS_RIGHT_OP (root->right) &&
3934 IS_LEFT_OP (root->left))
3937 if (!SPEC_USIGN (TETYPE (root->left->left)))
3940 if (!IS_AST_LIT_VALUE (root->left->right) ||
3941 !IS_AST_LIT_VALUE (root->right->right))
3944 /* make sure it is the same symbol */
3945 if (!isAstEqual (root->left->left,
3949 if (AST_LIT_VALUE (root->right->right) != 1)
3952 if (AST_LIT_VALUE (root->left->right) !=
3953 (getSize (TTYPE (root->left->left)) * 8 - 1))
3956 /* whew got the first case : create the AST */
3957 return newNode (RRC, root->left->left, NULL);
3961 /* not found return root */
3965 /*-----------------------------------------------------------------*/
3966 /* optimizeCompare - otimizes compares for bit variables */
3967 /*-----------------------------------------------------------------*/
3969 optimizeCompare (ast * root)
3971 ast *optExpr = NULL;
3974 unsigned int litValue;
3976 /* if nothing then return nothing */
3980 /* if not a compare op then do leaves */
3981 if (!IS_COMPARE_OP (root))
3983 root->left = optimizeCompare (root->left);
3984 root->right = optimizeCompare (root->right);
3988 /* if left & right are the same then depending
3989 of the operation do */
3990 if (isAstEqual (root->left, root->right))
3992 switch (root->opval.op)
3997 optExpr = newAst_VALUE (constVal ("0"));
4002 optExpr = newAst_VALUE (constVal ("1"));
4006 return decorateType (optExpr);
4009 vleft = (root->left->type == EX_VALUE ?
4010 root->left->opval.val : NULL);
4012 vright = (root->right->type == EX_VALUE ?
4013 root->right->opval.val : NULL);
4015 /* if left is a BITVAR in BITSPACE */
4016 /* and right is a LITERAL then opt- */
4017 /* imize else do nothing */
4018 if (vleft && vright &&
4019 IS_BITVAR (vleft->etype) &&
4020 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4021 IS_LITERAL (vright->etype))
4024 /* if right side > 1 then comparison may never succeed */
4025 if ((litValue = (int) floatFromVal (vright)) > 1)
4027 werror (W_BAD_COMPARE);
4033 switch (root->opval.op)
4035 case '>': /* bit value greater than 1 cannot be */
4036 werror (W_BAD_COMPARE);
4040 case '<': /* bit value < 1 means 0 */
4042 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4045 case LE_OP: /* bit value <= 1 means no check */
4046 optExpr = newAst_VALUE (vright);
4049 case GE_OP: /* bit value >= 1 means only check for = */
4051 optExpr = newAst_VALUE (vleft);
4056 { /* literal is zero */
4057 switch (root->opval.op)
4059 case '<': /* bit value < 0 cannot be */
4060 werror (W_BAD_COMPARE);
4064 case '>': /* bit value > 0 means 1 */
4066 optExpr = newAst_VALUE (vleft);
4069 case LE_OP: /* bit value <= 0 means no check */
4070 case GE_OP: /* bit value >= 0 means no check */
4071 werror (W_BAD_COMPARE);
4075 case EQ_OP: /* bit == 0 means ! of bit */
4076 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4080 return decorateType (resolveSymbols (optExpr));
4081 } /* end-of-if of BITVAR */
4086 /*-----------------------------------------------------------------*/
4087 /* addSymToBlock : adds the symbol to the first block we find */
4088 /*-----------------------------------------------------------------*/
4090 addSymToBlock (symbol * sym, ast * tree)
4092 /* reached end of tree or a leaf */
4093 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4097 if (IS_AST_OP (tree) &&
4098 tree->opval.op == BLOCK)
4101 symbol *lsym = copySymbol (sym);
4103 lsym->next = AST_VALUES (tree, sym);
4104 AST_VALUES (tree, sym) = lsym;
4108 addSymToBlock (sym, tree->left);
4109 addSymToBlock (sym, tree->right);
4112 /*-----------------------------------------------------------------*/
4113 /* processRegParms - do processing for register parameters */
4114 /*-----------------------------------------------------------------*/
4116 processRegParms (value * args, ast * body)
4120 if (IS_REGPARM (args->etype))
4121 addSymToBlock (args->sym, body);
4126 /*-----------------------------------------------------------------*/
4127 /* resetParmKey - resets the operandkeys for the symbols */
4128 /*-----------------------------------------------------------------*/
4129 DEFSETFUNC (resetParmKey)
4140 /*-----------------------------------------------------------------*/
4141 /* createFunction - This is the key node that calls the iCode for */
4142 /* generating the code for a function. Note code */
4143 /* is generated function by function, later when */
4144 /* add inter-procedural analysis this will change */
4145 /*-----------------------------------------------------------------*/
4147 createFunction (symbol * name, ast * body)
4153 iCode *piCode = NULL;
4155 /* if check function return 0 then some problem */
4156 if (checkFunction (name) == 0)
4159 /* create a dummy block if none exists */
4161 body = newNode (BLOCK, NULL, NULL);
4165 /* check if the function name already in the symbol table */
4166 if ((csym = findSym (SymbolTab, NULL, name->name)))
4169 /* special case for compiler defined functions
4170 we need to add the name to the publics list : this
4171 actually means we are now compiling the compiler
4175 addSet (&publics, name);
4181 allocVariables (name);
4183 name->lastLine = yylineno;
4185 processFuncArgs (currFunc, 0);
4187 /* set the stack pointer */
4188 /* PENDING: check this for the mcs51 */
4189 stackPtr = -port->stack.direction * port->stack.call_overhead;
4190 if (IS_ISR (name->etype))
4191 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4192 if (IS_RENT (name->etype) || options.stackAuto)
4193 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4195 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4197 fetype = getSpec (name->type); /* get the specifier for the function */
4198 /* if this is a reentrant function then */
4199 if (IS_RENT (fetype))
4202 allocParms (name->args); /* allocate the parameters */
4204 /* do processing for parameters that are passed in registers */
4205 processRegParms (name->args, body);
4207 /* set the stack pointer */
4211 /* allocate & autoinit the block variables */
4212 processBlockVars (body, &stack, ALLOCATE);
4214 /* save the stack information */
4215 if (options.useXstack)
4216 name->xstack = SPEC_STAK (fetype) = stack;
4218 name->stack = SPEC_STAK (fetype) = stack;
4220 /* name needs to be mangled */
4221 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4223 body = resolveSymbols (body); /* resolve the symbols */
4224 body = decorateType (body); /* propagateType & do semantic checks */
4226 ex = newAst_VALUE (symbolVal (name)); /* create name */
4227 ex = newNode (FUNCTION, ex, body);
4228 ex->values.args = name->args;
4232 werror (E_FUNC_NO_CODE, name->name);
4236 /* create the node & generate intermediate code */
4238 codeOutFile = code->oFile;
4239 piCode = iCodeFromAst (ex);
4243 werror (E_FUNC_NO_CODE, name->name);
4247 eBBlockFromiCode (piCode);
4249 /* if there are any statics then do them */
4252 GcurMemmap = statsg;
4253 codeOutFile = statsg->oFile;
4254 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4260 /* dealloc the block variables */
4261 processBlockVars (body, &stack, DEALLOCATE);
4262 /* deallocate paramaters */
4263 deallocParms (name->args);
4265 if (IS_RENT (fetype))
4268 /* we are done freeup memory & cleanup */
4273 addSet (&operKeyReset, name);
4274 applyToSet (operKeyReset, resetParmKey);
4277 cdbStructBlock (1, cdbFile);
4279 cleanUpLevel (LabelTab, 0);
4280 cleanUpBlock (StructTab, 1);
4281 cleanUpBlock (TypedefTab, 1);
4283 xstack->syms = NULL;
4284 istack->syms = NULL;
4289 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4290 /*-----------------------------------------------------------------*/
4291 /* ast_print : prints the ast (for debugging purposes) */
4292 /*-----------------------------------------------------------------*/
4294 void ast_print (ast * tree, FILE *outfile, int indent)
4299 /* can print only decorated trees */
4300 if (!tree->decorated) return;
4302 /* if any child is an error | this one is an error do nothing */
4303 if (tree->isError ||
4304 (tree->left && tree->left->isError) ||
4305 (tree->right && tree->right->isError)) {
4306 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4310 /* print the line */
4311 /* if not block & function */
4312 if (tree->type == EX_OP &&
4313 (tree->opval.op != FUNCTION &&
4314 tree->opval.op != BLOCK &&
4315 tree->opval.op != NULLOP)) {
4318 if (tree->opval.op == FUNCTION) {
4319 fprintf(outfile,"FUNCTION (%p) type (",tree);
4320 printTypeChain (tree->ftype,outfile);
4321 fprintf(outfile,")\n");
4322 ast_print(tree->left,outfile,indent+4);
4323 ast_print(tree->right,outfile,indent+4);
4326 if (tree->opval.op == BLOCK) {
4327 symbol *decls = tree->values.sym;
4328 fprintf(outfile,"{\n");
4330 INDENT(indent+4,outfile);
4331 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4332 printTypeChain(decls->type,outfile);
4333 fprintf(outfile,")\n");
4335 decls = decls->next;
4337 ast_print(tree->right,outfile,indent+4);
4338 fprintf(outfile,"}\n");
4341 if (tree->opval.op == NULLOP) {
4342 fprintf(outfile,"\n");
4343 ast_print(tree->left,outfile,indent);
4344 fprintf(outfile,"\n");
4345 ast_print(tree->right,outfile,indent);
4348 INDENT(indent,outfile);
4350 /*------------------------------------------------------------------*/
4351 /*----------------------------*/
4352 /* leaf has been reached */
4353 /*----------------------------*/
4354 /* if this is of type value */
4355 /* just get the type */
4356 if (tree->type == EX_VALUE) {
4358 if (IS_LITERAL (tree->opval.val->etype)) {
4359 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4360 (int) floatFromVal(tree->opval.val),
4361 (int) floatFromVal(tree->opval.val),
4362 floatFromVal(tree->opval.val));
4363 } else if (tree->opval.val->sym) {
4364 /* if the undefined flag is set then give error message */
4365 if (tree->opval.val->sym->undefined) {
4366 fprintf(outfile,"UNDEFINED SYMBOL ");
4368 fprintf(outfile,"SYMBOL ");
4370 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4373 fprintf(outfile," type (");
4374 printTypeChain(tree->ftype,outfile);
4375 fprintf(outfile,")\n");
4377 fprintf(outfile,"\n");
4382 /* if type link for the case of cast */
4383 if (tree->type == EX_LINK) {
4384 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4385 printTypeChain(tree->opval.lnk,outfile);
4386 fprintf(outfile,")\n");
4391 /* depending on type of operator do */
4393 switch (tree->opval.op) {
4394 /*------------------------------------------------------------------*/
4395 /*----------------------------*/
4397 /*----------------------------*/
4399 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4400 printTypeChain(tree->ftype,outfile);
4401 fprintf(outfile,")\n");
4402 ast_print(tree->left,outfile,indent+4);
4403 ast_print(tree->right,outfile,indent+4);
4406 /*------------------------------------------------------------------*/
4407 /*----------------------------*/
4409 /*----------------------------*/
4411 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4412 printTypeChain(tree->ftype,outfile);
4413 fprintf(outfile,")\n");
4414 ast_print(tree->left,outfile,indent+4);
4415 ast_print(tree->right,outfile,indent+4);
4418 /*------------------------------------------------------------------*/
4419 /*----------------------------*/
4420 /* struct/union pointer */
4421 /*----------------------------*/
4423 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4424 printTypeChain(tree->ftype,outfile);
4425 fprintf(outfile,")\n");
4426 ast_print(tree->left,outfile,indent+4);
4427 ast_print(tree->right,outfile,indent+4);
4430 /*------------------------------------------------------------------*/
4431 /*----------------------------*/
4432 /* ++/-- operation */
4433 /*----------------------------*/
4434 case INC_OP: /* incerement operator unary so left only */
4435 fprintf(outfile,"INC_OP (%p) type (",tree);
4436 printTypeChain(tree->ftype,outfile);
4437 fprintf(outfile,")\n");
4438 ast_print(tree->left,outfile,indent+4);
4442 fprintf(outfile,"DEC_OP (%p) type (",tree);
4443 printTypeChain(tree->ftype,outfile);
4444 fprintf(outfile,")\n");
4445 ast_print(tree->left,outfile,indent+4);
4448 /*------------------------------------------------------------------*/
4449 /*----------------------------*/
4451 /*----------------------------*/
4454 fprintf(outfile,"& (%p) type (",tree);
4455 printTypeChain(tree->ftype,outfile);
4456 fprintf(outfile,")\n");
4457 ast_print(tree->left,outfile,indent+4);
4458 ast_print(tree->right,outfile,indent+4);
4460 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4461 printTypeChain(tree->ftype,outfile);
4462 fprintf(outfile,")\n");
4463 ast_print(tree->left,outfile,indent+4);
4464 ast_print(tree->right,outfile,indent+4);
4467 /*----------------------------*/
4469 /*----------------------------*/
4471 fprintf(outfile,"OR (%p) type (",tree);
4472 printTypeChain(tree->ftype,outfile);
4473 fprintf(outfile,")\n");
4474 ast_print(tree->left,outfile,indent+4);
4475 ast_print(tree->right,outfile,indent+4);
4477 /*------------------------------------------------------------------*/
4478 /*----------------------------*/
4480 /*----------------------------*/
4482 fprintf(outfile,"XOR (%p) type (",tree);
4483 printTypeChain(tree->ftype,outfile);
4484 fprintf(outfile,")\n");
4485 ast_print(tree->left,outfile,indent+4);
4486 ast_print(tree->right,outfile,indent+4);
4489 /*------------------------------------------------------------------*/
4490 /*----------------------------*/
4492 /*----------------------------*/
4494 fprintf(outfile,"DIV (%p) type (",tree);
4495 printTypeChain(tree->ftype,outfile);
4496 fprintf(outfile,")\n");
4497 ast_print(tree->left,outfile,indent+4);
4498 ast_print(tree->right,outfile,indent+4);
4500 /*------------------------------------------------------------------*/
4501 /*----------------------------*/
4503 /*----------------------------*/
4505 fprintf(outfile,"MOD (%p) type (",tree);
4506 printTypeChain(tree->ftype,outfile);
4507 fprintf(outfile,")\n");
4508 ast_print(tree->left,outfile,indent+4);
4509 ast_print(tree->right,outfile,indent+4);
4512 /*------------------------------------------------------------------*/
4513 /*----------------------------*/
4514 /* address dereference */
4515 /*----------------------------*/
4516 case '*': /* can be unary : if right is null then unary operation */
4518 fprintf(outfile,"DEREF (%p) type (",tree);
4519 printTypeChain(tree->ftype,outfile);
4520 fprintf(outfile,")\n");
4521 ast_print(tree->left,outfile,indent+4);
4524 /*------------------------------------------------------------------*/
4525 /*----------------------------*/
4526 /* multiplication */
4527 /*----------------------------*/
4528 fprintf(outfile,"MULT (%p) type (",tree);
4529 printTypeChain(tree->ftype,outfile);
4530 fprintf(outfile,")\n");
4531 ast_print(tree->left,outfile,indent+4);
4532 ast_print(tree->right,outfile,indent+4);
4536 /*------------------------------------------------------------------*/
4537 /*----------------------------*/
4538 /* unary '+' operator */
4539 /*----------------------------*/
4543 fprintf(outfile,"UPLUS (%p) type (",tree);
4544 printTypeChain(tree->ftype,outfile);
4545 fprintf(outfile,")\n");
4546 ast_print(tree->left,outfile,indent+4);
4548 /*------------------------------------------------------------------*/
4549 /*----------------------------*/
4551 /*----------------------------*/
4552 fprintf(outfile,"ADD (%p) type (",tree);
4553 printTypeChain(tree->ftype,outfile);
4554 fprintf(outfile,")\n");
4555 ast_print(tree->left,outfile,indent+4);
4556 ast_print(tree->right,outfile,indent+4);
4559 /*------------------------------------------------------------------*/
4560 /*----------------------------*/
4562 /*----------------------------*/
4563 case '-': /* can be unary */
4565 fprintf(outfile,"UMINUS (%p) type (",tree);
4566 printTypeChain(tree->ftype,outfile);
4567 fprintf(outfile,")\n");
4568 ast_print(tree->left,outfile,indent+4);
4570 /*------------------------------------------------------------------*/
4571 /*----------------------------*/
4573 /*----------------------------*/
4574 fprintf(outfile,"SUB (%p) type (",tree);
4575 printTypeChain(tree->ftype,outfile);
4576 fprintf(outfile,")\n");
4577 ast_print(tree->left,outfile,indent+4);
4578 ast_print(tree->right,outfile,indent+4);
4581 /*------------------------------------------------------------------*/
4582 /*----------------------------*/
4584 /*----------------------------*/
4586 fprintf(outfile,"COMPL (%p) type (",tree);
4587 printTypeChain(tree->ftype,outfile);
4588 fprintf(outfile,")\n");
4589 ast_print(tree->left,outfile,indent+4);
4591 /*------------------------------------------------------------------*/
4592 /*----------------------------*/
4594 /*----------------------------*/
4596 fprintf(outfile,"NOT (%p) type (",tree);
4597 printTypeChain(tree->ftype,outfile);
4598 fprintf(outfile,")\n");
4599 ast_print(tree->left,outfile,indent+4);
4601 /*------------------------------------------------------------------*/
4602 /*----------------------------*/
4604 /*----------------------------*/
4606 fprintf(outfile,"RRC (%p) type (",tree);
4607 printTypeChain(tree->ftype,outfile);
4608 fprintf(outfile,")\n");
4609 ast_print(tree->left,outfile,indent+4);
4613 fprintf(outfile,"RLC (%p) type (",tree);
4614 printTypeChain(tree->ftype,outfile);
4615 fprintf(outfile,")\n");
4616 ast_print(tree->left,outfile,indent+4);
4619 fprintf(outfile,"GETHBIT (%p) type (",tree);
4620 printTypeChain(tree->ftype,outfile);
4621 fprintf(outfile,")\n");
4622 ast_print(tree->left,outfile,indent+4);
4625 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4626 printTypeChain(tree->ftype,outfile);
4627 fprintf(outfile,")\n");
4628 ast_print(tree->left,outfile,indent+4);
4629 ast_print(tree->right,outfile,indent+4);
4632 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4633 printTypeChain(tree->ftype,outfile);
4634 fprintf(outfile,")\n");
4635 ast_print(tree->left,outfile,indent+4);
4636 ast_print(tree->right,outfile,indent+4);
4638 /*------------------------------------------------------------------*/
4639 /*----------------------------*/
4641 /*----------------------------*/
4642 case CAST: /* change the type */
4643 fprintf(outfile,"CAST (%p) type (",tree);
4644 printTypeChain(tree->ftype,outfile);
4645 fprintf(outfile,")\n");
4646 ast_print(tree->right,outfile,indent+4);
4650 fprintf(outfile,"ANDAND (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+4);
4654 ast_print(tree->right,outfile,indent+4);
4657 fprintf(outfile,"OROR (%p) type (",tree);
4658 printTypeChain(tree->ftype,outfile);
4659 fprintf(outfile,")\n");
4660 ast_print(tree->left,outfile,indent+4);
4661 ast_print(tree->right,outfile,indent+4);
4664 /*------------------------------------------------------------------*/
4665 /*----------------------------*/
4666 /* comparison operators */
4667 /*----------------------------*/
4669 fprintf(outfile,"GT(>) (%p) type (",tree);
4670 printTypeChain(tree->ftype,outfile);
4671 fprintf(outfile,")\n");
4672 ast_print(tree->left,outfile,indent+4);
4673 ast_print(tree->right,outfile,indent+4);
4676 fprintf(outfile,"LT(<) (%p) type (",tree);
4677 printTypeChain(tree->ftype,outfile);
4678 fprintf(outfile,")\n");
4679 ast_print(tree->left,outfile,indent+4);
4680 ast_print(tree->right,outfile,indent+4);
4683 fprintf(outfile,"LE(<=) (%p) type (",tree);
4684 printTypeChain(tree->ftype,outfile);
4685 fprintf(outfile,")\n");
4686 ast_print(tree->left,outfile,indent+4);
4687 ast_print(tree->right,outfile,indent+4);
4690 fprintf(outfile,"GE(>=) (%p) type (",tree);
4691 printTypeChain(tree->ftype,outfile);
4692 fprintf(outfile,")\n");
4693 ast_print(tree->left,outfile,indent+4);
4694 ast_print(tree->right,outfile,indent+4);
4697 fprintf(outfile,"EQ(==) (%p) type (",tree);
4698 printTypeChain(tree->ftype,outfile);
4699 fprintf(outfile,")\n");
4700 ast_print(tree->left,outfile,indent+4);
4701 ast_print(tree->right,outfile,indent+4);
4704 fprintf(outfile,"NE(!=) (%p) type (",tree);
4705 printTypeChain(tree->ftype,outfile);
4706 fprintf(outfile,")\n");
4707 ast_print(tree->left,outfile,indent+4);
4708 ast_print(tree->right,outfile,indent+4);
4709 /*------------------------------------------------------------------*/
4710 /*----------------------------*/
4712 /*----------------------------*/
4713 case SIZEOF: /* evaluate wihout code generation */
4714 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4717 /*------------------------------------------------------------------*/
4718 /*----------------------------*/
4719 /* conditional operator '?' */
4720 /*----------------------------*/
4722 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4723 printTypeChain(tree->ftype,outfile);
4724 fprintf(outfile,")\n");
4725 ast_print(tree->left,outfile,indent+4);
4726 ast_print(tree->right,outfile,indent+4);
4729 fprintf(outfile,"COLON(:) (%p) type (",tree);
4730 printTypeChain(tree->ftype,outfile);
4731 fprintf(outfile,")\n");
4732 ast_print(tree->left,outfile,indent+4);
4733 ast_print(tree->right,outfile,indent+4);
4736 /*------------------------------------------------------------------*/
4737 /*----------------------------*/
4738 /* assignment operators */
4739 /*----------------------------*/
4741 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4742 printTypeChain(tree->ftype,outfile);
4743 fprintf(outfile,")\n");
4744 ast_print(tree->left,outfile,indent+4);
4745 ast_print(tree->right,outfile,indent+4);
4748 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4749 printTypeChain(tree->ftype,outfile);
4750 fprintf(outfile,")\n");
4751 ast_print(tree->left,outfile,indent+4);
4752 ast_print(tree->right,outfile,indent+4);
4755 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4756 printTypeChain(tree->ftype,outfile);
4757 fprintf(outfile,")\n");
4758 ast_print(tree->left,outfile,indent+4);
4759 ast_print(tree->right,outfile,indent+4);
4762 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4763 printTypeChain(tree->ftype,outfile);
4764 fprintf(outfile,")\n");
4765 ast_print(tree->left,outfile,indent+4);
4766 ast_print(tree->right,outfile,indent+4);
4769 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+4);
4773 ast_print(tree->right,outfile,indent+4);
4776 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+4);
4780 ast_print(tree->right,outfile,indent+4);
4783 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4784 printTypeChain(tree->ftype,outfile);
4785 fprintf(outfile,")\n");
4786 ast_print(tree->left,outfile,indent+4);
4787 ast_print(tree->right,outfile,indent+4);
4789 /*------------------------------------------------------------------*/
4790 /*----------------------------*/
4792 /*----------------------------*/
4794 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4795 printTypeChain(tree->ftype,outfile);
4796 fprintf(outfile,")\n");
4797 ast_print(tree->left,outfile,indent+4);
4798 ast_print(tree->right,outfile,indent+4);
4800 /*------------------------------------------------------------------*/
4801 /*----------------------------*/
4803 /*----------------------------*/
4805 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4806 printTypeChain(tree->ftype,outfile);
4807 fprintf(outfile,")\n");
4808 ast_print(tree->left,outfile,indent+4);
4809 ast_print(tree->right,outfile,indent+4);
4811 /*------------------------------------------------------------------*/
4812 /*----------------------------*/
4813 /* straight assignemnt */
4814 /*----------------------------*/
4816 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4817 printTypeChain(tree->ftype,outfile);
4818 fprintf(outfile,")\n");
4819 ast_print(tree->left,outfile,indent+4);
4820 ast_print(tree->right,outfile,indent+4);
4822 /*------------------------------------------------------------------*/
4823 /*----------------------------*/
4824 /* comma operator */
4825 /*----------------------------*/
4827 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4828 printTypeChain(tree->ftype,outfile);
4829 fprintf(outfile,")\n");
4830 ast_print(tree->left,outfile,indent+4);
4831 ast_print(tree->right,outfile,indent+4);
4833 /*------------------------------------------------------------------*/
4834 /*----------------------------*/
4836 /*----------------------------*/
4839 fprintf(outfile,"CALL (%p) type (",tree);
4840 printTypeChain(tree->ftype,outfile);
4841 fprintf(outfile,")\n");
4842 ast_print(tree->left,outfile,indent+4);
4843 ast_print(tree->right,outfile,indent+4);
4846 fprintf(outfile,"PARM ");
4847 ast_print(tree->left,outfile,indent+4);
4848 if (tree->right && !IS_AST_PARAM(tree->right)) {
4849 fprintf(outfile,"PARM ");
4850 ast_print(tree->right,outfile,indent+4);
4853 /*------------------------------------------------------------------*/
4854 /*----------------------------*/
4855 /* return statement */
4856 /*----------------------------*/
4858 fprintf(outfile,"RETURN (%p) type (",tree);
4859 printTypeChain(tree->right->ftype,outfile);
4860 fprintf(outfile,")\n");
4861 ast_print(tree->right,outfile,indent+4);
4863 /*------------------------------------------------------------------*/
4864 /*----------------------------*/
4865 /* label statement */
4866 /*----------------------------*/
4868 fprintf(outfile,"LABEL (%p)",tree);
4869 ast_print(tree->left,outfile,indent+4);
4870 ast_print(tree->right,outfile,indent);
4872 /*------------------------------------------------------------------*/
4873 /*----------------------------*/
4874 /* switch statement */
4875 /*----------------------------*/
4879 fprintf(outfile,"SWITCH (%p) ",tree);
4880 ast_print(tree->left,outfile,0);
4881 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4882 INDENT(indent+4,outfile);
4883 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4884 (int) floatFromVal(val),
4885 tree->values.switchVals.swNum,
4886 (int) floatFromVal(val));
4888 ast_print(tree->right,outfile,indent);
4891 /*------------------------------------------------------------------*/
4892 /*----------------------------*/
4894 /*----------------------------*/
4896 ast_print(tree->left,outfile,indent);
4897 INDENT(indent,outfile);
4898 fprintf(outfile,"IF (%p) \n",tree);
4899 if (tree->trueLabel) {
4900 INDENT(indent,outfile);
4901 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4903 if (tree->falseLabel) {
4904 INDENT(indent,outfile);
4905 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4907 ast_print(tree->right,outfile,indent);
4909 /*------------------------------------------------------------------*/
4910 /*----------------------------*/
4912 /*----------------------------*/
4914 fprintf(outfile,"FOR (%p) \n",tree);
4915 if (AST_FOR( tree, initExpr)) {
4916 INDENT(indent+4,outfile);
4917 fprintf(outfile,"INIT EXPR ");
4918 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4920 if (AST_FOR( tree, condExpr)) {
4921 INDENT(indent+4,outfile);
4922 fprintf(outfile,"COND EXPR ");
4923 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4925 if (AST_FOR( tree, loopExpr)) {
4926 INDENT(indent+4,outfile);
4927 fprintf(outfile,"LOOP EXPR ");
4928 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4930 fprintf(outfile,"FOR LOOP BODY \n");
4931 ast_print(tree->left,outfile,indent+4);
4940 ast_print(t,stdout,1);