1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
73 newAst_ (unsigned type)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
90 newAst_VALUE (value * val)
92 ast *ex = newAst_ (EX_VALUE);
98 newAst_OP (unsigned op)
100 ast *ex = newAst_ (EX_OP);
106 newAst_LINK (sym_link * val)
108 ast *ex = newAst_ (EX_LINK);
114 newAst_STMNT (unsigned val)
116 ast *ex = newAst_ (EX_STMNT);
117 ex->opval.stmnt = val;
121 /*-----------------------------------------------------------------*/
122 /* newNode - creates a new node */
123 /*-----------------------------------------------------------------*/
125 newNode (long op, ast * left, ast * right)
136 /*-----------------------------------------------------------------*/
137 /* newIfxNode - creates a new Ifx Node */
138 /*-----------------------------------------------------------------*/
140 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
144 /* if this is a literal then we already know the result */
145 if (condAst->etype && IS_LITERAL (condAst->etype))
147 /* then depending on the expression value */
148 if (floatFromVal (condAst->opval.val))
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (trueLabel)),
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (falseLabel)),
159 ifxNode = newNode (IFX, condAst, NULL);
160 ifxNode->trueLabel = trueLabel;
161 ifxNode->falseLabel = falseLabel;
167 /*-----------------------------------------------------------------*/
168 /* copyAstValues - copies value portion of ast if needed */
169 /*-----------------------------------------------------------------*/
171 copyAstValues (ast * dest, ast * src)
173 switch (src->opval.op)
176 dest->values.sym = copySymbolChain (src->values.sym);
180 dest->values.switchVals.swVals =
181 copyValue (src->values.switchVals.swVals);
182 dest->values.switchVals.swDefault =
183 src->values.switchVals.swDefault;
184 dest->values.switchVals.swNum =
185 src->values.switchVals.swNum;
189 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
190 strcpy (dest->values.inlineasm, src->values.inlineasm);
194 dest->values.constlist = copyLiteralList(src->values.constlist);
198 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
199 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
200 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
201 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
202 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
203 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
204 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
209 /*-----------------------------------------------------------------*/
210 /* copyAst - makes a copy of a given astession */
211 /*-----------------------------------------------------------------*/
220 dest = Safe_alloc ( sizeof (ast));
222 dest->type = src->type;
223 dest->lineno = src->lineno;
224 dest->level = src->level;
225 dest->funcName = src->funcName;
228 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
230 /* if this is a leaf */
232 if (src->type == EX_VALUE)
234 dest->opval.val = copyValue (src->opval.val);
239 if (src->type == EX_LINK)
241 dest->opval.lnk = copyLinkChain (src->opval.lnk);
245 dest->opval.op = src->opval.op;
247 /* if this is a node that has special values */
248 copyAstValues (dest, src);
250 dest->trueLabel = copySymbol (src->trueLabel);
251 dest->falseLabel = copySymbol (src->falseLabel);
252 dest->left = copyAst (src->left);
253 dest->right = copyAst (src->right);
259 /*-----------------------------------------------------------------*/
260 /* hasSEFcalls - returns TRUE if tree has a function call */
261 /*-----------------------------------------------------------------*/
263 hasSEFcalls (ast * tree)
268 if (tree->type == EX_OP &&
269 (tree->opval.op == CALL ||
270 tree->opval.op == PCALL ||
271 tree->opval.op == '=' ||
272 tree->opval.op == INC_OP ||
273 tree->opval.op == DEC_OP))
276 return (hasSEFcalls (tree->left) |
277 hasSEFcalls (tree->right));
280 /*-----------------------------------------------------------------*/
281 /* isAstEqual - compares two asts & returns 1 if they are equal */
282 /*-----------------------------------------------------------------*/
284 isAstEqual (ast * t1, ast * t2)
293 if (t1->type != t2->type)
299 if (t1->opval.op != t2->opval.op)
301 return (isAstEqual (t1->left, t2->left) &&
302 isAstEqual (t1->right, t2->right));
306 if (t1->opval.val->sym)
308 if (!t2->opval.val->sym)
311 return isSymbolEqual (t1->opval.val->sym,
316 if (t2->opval.val->sym)
319 return (floatFromVal (t1->opval.val) ==
320 floatFromVal (t2->opval.val));
324 /* only compare these two types */
332 /*-----------------------------------------------------------------*/
333 /* resolveSymbols - resolve symbols from the symbol table */
334 /*-----------------------------------------------------------------*/
336 resolveSymbols (ast * tree)
338 /* walk the entire tree and check for values */
339 /* with symbols if we find one then replace */
340 /* symbol with that from the symbol table */
346 /* if not block & function */
347 if (tree->type == EX_OP &&
348 (tree->opval.op != FUNCTION &&
349 tree->opval.op != BLOCK &&
350 tree->opval.op != NULLOP))
352 filename = tree->filename;
353 lineno = tree->lineno;
356 /* make sure we resolve the true & false labels for ifx */
357 if (tree->type == EX_OP && tree->opval.op == IFX)
363 if ((csym = findSym (LabelTab, tree->trueLabel,
364 tree->trueLabel->name)))
365 tree->trueLabel = csym;
367 werror (E_LABEL_UNDEF, tree->trueLabel->name);
370 if (tree->falseLabel)
372 if ((csym = findSym (LabelTab,
374 tree->falseLabel->name)))
375 tree->falseLabel = csym;
377 werror (E_LABEL_UNDEF, tree->falseLabel->name);
382 /* if this is a label resolve it from the labelTab */
383 if (IS_AST_VALUE (tree) &&
384 tree->opval.val->sym &&
385 tree->opval.val->sym->islbl)
388 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
389 tree->opval.val->sym->name);
392 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
394 tree->opval.val->sym = csym;
396 goto resolveChildren;
399 /* do only for leafs */
400 if (IS_AST_VALUE (tree) &&
401 tree->opval.val->sym &&
402 !tree->opval.val->sym->implicit)
405 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
407 /* if found in the symbol table & they r not the same */
408 if (csym && tree->opval.val->sym != csym)
410 tree->opval.val->sym = csym;
411 tree->opval.val->type = csym->type;
412 tree->opval.val->etype = csym->etype;
415 /* if not found in the symbol table */
416 /* mark it as undefined assume it is */
417 /* an integer in data space */
418 if (!csym && !tree->opval.val->sym->implicit)
421 /* if this is a function name then */
422 /* mark it as returning an int */
425 tree->opval.val->sym->type = newLink ();
426 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
427 tree->opval.val->sym->type->next =
428 tree->opval.val->sym->etype = newIntLink ();
429 tree->opval.val->etype = tree->opval.val->etype;
430 tree->opval.val->type = tree->opval.val->sym->type;
431 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
432 allocVariables (tree->opval.val->sym);
436 tree->opval.val->sym->undefined = 1;
437 tree->opval.val->type =
438 tree->opval.val->etype = newIntLink ();
439 tree->opval.val->sym->type =
440 tree->opval.val->sym->etype = newIntLink ();
446 resolveSymbols (tree->left);
447 resolveSymbols (tree->right);
452 /*-----------------------------------------------------------------*/
453 /* setAstLineno - walks a ast tree & sets the line number */
454 /*-----------------------------------------------------------------*/
456 setAstLineno (ast * tree, int lineno)
461 tree->lineno = lineno;
462 setAstLineno (tree->left, lineno);
463 setAstLineno (tree->right, lineno);
467 /*-----------------------------------------------------------------*/
468 /* funcOfType :- function of type with name */
469 /*-----------------------------------------------------------------*/
471 funcOfType (char *name, sym_link * type, sym_link * argType,
475 /* create the symbol */
476 sym = newSymbol (name, 0);
478 /* setup return value */
479 sym->type = newLink ();
480 DCL_TYPE (sym->type) = FUNCTION;
481 sym->type->next = copyLinkChain (type);
482 sym->etype = getSpec (sym->type);
483 FUNC_ISREENT(sym->type) = rent;
485 /* if arguments required */
489 args = FUNC_ARGS(sym->type) = newValue ();
493 args->type = copyLinkChain (argType);
494 args->etype = getSpec (args->type);
495 SPEC_EXTR(args->etype)=1;
498 args = args->next = newValue ();
505 allocVariables (sym);
510 /*-----------------------------------------------------------------*/
511 /* funcOfTypeVarg :- function of type with name and argtype */
512 /*-----------------------------------------------------------------*/
514 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
519 /* create the symbol */
520 sym = newSymbol (name, 0);
522 /* setup return value */
523 sym->type = newLink ();
524 DCL_TYPE (sym->type) = FUNCTION;
525 sym->type->next = typeFromStr(rtype);
526 sym->etype = getSpec (sym->type);
528 /* if arguments required */
531 args = FUNC_ARGS(sym->type) = newValue ();
533 for ( i = 0 ; i < nArgs ; i++ ) {
534 args->type = typeFromStr(atypes[i]);
535 args->etype = getSpec (args->type);
536 SPEC_EXTR(args->etype)=1;
537 if ((i + 1) == nArgs) break;
538 args = args->next = newValue ();
545 allocVariables (sym);
550 /*-----------------------------------------------------------------*/
551 /* reverseParms - will reverse a parameter tree */
552 /*-----------------------------------------------------------------*/
554 reverseParms (ast * ptree)
560 /* top down if we find a nonParm tree then quit */
561 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
564 ptree->left = ptree->right;
565 ptree->right = ttree;
566 reverseParms (ptree->left);
567 reverseParms (ptree->right);
573 /*-----------------------------------------------------------------*/
574 /* processParms - makes sure the parameters are okay and do some */
575 /* processing with them */
576 /*-----------------------------------------------------------------*/
578 processParms (ast * func,
581 int *parmNumber, // unused, although updated
584 /* if none of them exist */
585 if (!defParm && !actParm)
589 if (getenv("DEBUG_SANITY")) {
590 fprintf (stderr, "processParms: %s ", defParm->name);
592 /* make sure the type is complete and sane */
593 checkTypeSanity(defParm->etype, defParm->name);
596 /* if the function is being called via a pointer & */
597 /* it has not been defined a reentrant then we cannot */
598 /* have parameters */
599 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
601 werror (W_NONRENT_ARGS);
605 /* if defined parameters ended but actual parameters */
606 /* exist and this is not defined as a variable arg */
607 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
609 werror (E_TOO_MANY_PARMS);
613 /* if defined parameters present but no actual parameters */
614 if (defParm && !actParm)
616 werror (E_TOO_FEW_PARMS);
620 if (IS_VOID(actParm->ftype)) {
621 werror (E_VOID_VALUE_USED);
625 /* If this is a varargs function... */
626 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
631 if (IS_CAST_OP (actParm)
632 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
634 /* Parameter was explicitly typecast; don't touch it. */
638 ftype = actParm->ftype;
640 /* If it's a small integer, upcast to int. */
641 if (IS_INTEGRAL (ftype)
642 && (getSize (ftype) < (unsigned) INTSIZE))
644 newType = newAst_LINK(INTTYPE);
647 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
649 newType = newAst_LINK (copyLinkChain(ftype));
650 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
653 if (IS_AGGREGATE (ftype))
655 newType = newAst_LINK (copyLinkChain (ftype));
656 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
660 /* cast required; change this op to a cast. */
661 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
663 actParm->type = EX_OP;
664 actParm->opval.op = CAST;
665 actParm->left = newType;
666 actParm->right = parmCopy;
667 decorateType (actParm);
669 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
671 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
672 processParms (func, NULL, actParm->right, parmNumber, rightmost));
677 /* if defined parameters ended but actual has not & */
679 if (!defParm && actParm &&
680 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
683 resolveSymbols (actParm);
684 /* if this is a PARAM node then match left & right */
685 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
687 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
688 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
692 /* If we have found a value node by following only right-hand links,
693 * then we know that there are no more values after us.
695 * Therefore, if there are more defined parameters, the caller didn't
698 if (rightmost && defParm->next)
700 werror (E_TOO_FEW_PARMS);
705 /* the parameter type must be at least castable */
706 if (compareType (defParm->type, actParm->ftype) == 0) {
707 werror (E_INCOMPAT_TYPES);
708 printFromToType (actParm->ftype, defParm->type);
712 /* if the parameter is castable then add the cast */
713 if (compareType (defParm->type, actParm->ftype) < 0)
715 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
717 /* now change the current one to a cast */
718 actParm->type = EX_OP;
719 actParm->opval.op = CAST;
720 actParm->left = newAst_LINK (defParm->type);
721 actParm->right = pTree;
722 actParm->etype = defParm->etype;
723 actParm->ftype = defParm->type;
724 actParm->decorated=0; /* force typechecking */
725 decorateType (actParm);
728 /* make a copy and change the regparm type to the defined parm */
729 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
730 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
734 /*-----------------------------------------------------------------*/
735 /* createIvalType - generates ival for basic types */
736 /*-----------------------------------------------------------------*/
738 createIvalType (ast * sym, sym_link * type, initList * ilist)
742 /* if initList is deep */
743 if (ilist->type == INIT_DEEP)
744 ilist = ilist->init.deep;
746 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
747 return decorateType (newNode ('=', sym, iExpr));
750 /*-----------------------------------------------------------------*/
751 /* createIvalStruct - generates initial value for structures */
752 /*-----------------------------------------------------------------*/
754 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
761 sflds = SPEC_STRUCT (type)->fields;
762 if (ilist->type != INIT_DEEP)
764 werror (E_INIT_STRUCT, "");
768 iloop = ilist->init.deep;
770 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
772 /* if we have come to end */
776 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
777 lAst = decorateType (resolveSymbols (lAst));
778 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
782 werror (W_EXCESS_INITIALIZERS, "struct",
783 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
790 /*-----------------------------------------------------------------*/
791 /* createIvalArray - generates code for array initialization */
792 /*-----------------------------------------------------------------*/
794 createIvalArray (ast * sym, sym_link * type, initList * ilist)
798 int lcnt = 0, size = 0;
799 literalList *literalL;
801 /* take care of the special case */
802 /* array of characters can be init */
804 if (IS_CHAR (type->next))
805 if ((rast = createIvalCharPtr (sym,
807 decorateType (resolveSymbols (list2expr (ilist))))))
809 return decorateType (resolveSymbols (rast));
811 /* not the special case */
812 if (ilist->type != INIT_DEEP)
814 werror (E_INIT_STRUCT, "");
818 iloop = ilist->init.deep;
819 lcnt = DCL_ELEM (type);
821 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
825 aSym = decorateType (resolveSymbols(sym));
827 rast = newNode(ARRAYINIT, aSym, NULL);
828 rast->values.constlist = literalL;
830 // Make sure size is set to length of initializer list.
837 if (lcnt && size > lcnt)
839 // Array size was specified, and we have more initializers than needed.
840 char *name=sym->opval.val->sym->name;
841 int lineno=sym->opval.val->sym->lineDef;
843 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
852 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
853 aSym = decorateType (resolveSymbols (aSym));
854 rast = createIval (aSym, type->next, iloop, rast);
855 iloop = (iloop ? iloop->next : NULL);
861 /* no of elements given and we */
862 /* have generated for all of them */
865 // there has to be a better way
866 char *name=sym->opval.val->sym->name;
867 int lineno=sym->opval.val->sym->lineDef;
868 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
875 /* if we have not been given a size */
876 if (!DCL_ELEM (type))
878 DCL_ELEM (type) = size;
881 return decorateType (resolveSymbols (rast));
885 /*-----------------------------------------------------------------*/
886 /* createIvalCharPtr - generates initial values for char pointers */
887 /*-----------------------------------------------------------------*/
889 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
893 /* if this is a pointer & right is a literal array then */
894 /* just assignment will do */
895 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
896 SPEC_SCLS (iexpr->etype) == S_CODE)
897 && IS_ARRAY (iexpr->ftype)))
898 return newNode ('=', sym, iexpr);
900 /* left side is an array so we have to assign each */
902 if ((IS_LITERAL (iexpr->etype) ||
903 SPEC_SCLS (iexpr->etype) == S_CODE)
904 && IS_ARRAY (iexpr->ftype))
906 /* for each character generate an assignment */
907 /* to the array element */
908 char *s = SPEC_CVAL (iexpr->etype).v_char;
913 rast = newNode (NULLOP,
917 newAst_VALUE (valueFromLit ((float) i))),
918 newAst_VALUE (valueFromLit (*s))));
922 rast = newNode (NULLOP,
926 newAst_VALUE (valueFromLit ((float) i))),
927 newAst_VALUE (valueFromLit (*s))));
928 return decorateType (resolveSymbols (rast));
934 /*-----------------------------------------------------------------*/
935 /* createIvalPtr - generates initial value for pointers */
936 /*-----------------------------------------------------------------*/
938 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
944 if (ilist->type == INIT_DEEP)
945 ilist = ilist->init.deep;
947 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
949 /* if character pointer */
950 if (IS_CHAR (type->next))
951 if ((rast = createIvalCharPtr (sym, type, iexpr)))
954 return newNode ('=', sym, iexpr);
957 /*-----------------------------------------------------------------*/
958 /* createIval - generates code for initial value */
959 /*-----------------------------------------------------------------*/
961 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
968 /* if structure then */
969 if (IS_STRUCT (type))
970 rast = createIvalStruct (sym, type, ilist);
972 /* if this is a pointer */
974 rast = createIvalPtr (sym, type, ilist);
976 /* if this is an array */
978 rast = createIvalArray (sym, type, ilist);
980 /* if type is SPECIFIER */
982 rast = createIvalType (sym, type, ilist);
985 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
987 return decorateType (resolveSymbols (rast));
990 /*-----------------------------------------------------------------*/
991 /* initAggregates - initialises aggregate variables with initv */
992 /*-----------------------------------------------------------------*/
993 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
994 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
997 /*-----------------------------------------------------------------*/
998 /* gatherAutoInit - creates assignment expressions for initial */
1000 /*-----------------------------------------------------------------*/
1002 gatherAutoInit (symbol * autoChain)
1009 for (sym = autoChain; sym; sym = sym->next)
1012 /* resolve the symbols in the ival */
1014 resolveIvalSym (sym->ival);
1016 /* if this is a static variable & has an */
1017 /* initial value the code needs to be lifted */
1018 /* here to the main portion since they can be */
1019 /* initialised only once at the start */
1020 if (IS_STATIC (sym->etype) && sym->ival &&
1021 SPEC_SCLS (sym->etype) != S_CODE)
1025 /* insert the symbol into the symbol table */
1026 /* with level = 0 & name = rname */
1027 newSym = copySymbol (sym);
1028 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1030 /* now lift the code to main */
1031 if (IS_AGGREGATE (sym->type)) {
1032 work = initAggregates (sym, sym->ival, NULL);
1034 if (getNelements(sym->type, sym->ival)>1) {
1035 werror (W_EXCESS_INITIALIZERS, "scalar",
1036 sym->name, sym->lineDef);
1038 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1039 list2expr (sym->ival));
1042 setAstLineno (work, sym->lineDef);
1046 staticAutos = newNode (NULLOP, staticAutos, work);
1053 /* if there is an initial value */
1054 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1056 if (IS_AGGREGATE (sym->type)) {
1057 work = initAggregates (sym, sym->ival, NULL);
1059 if (getNelements(sym->type, sym->ival)>1) {
1060 werror (W_EXCESS_INITIALIZERS, "scalar",
1061 sym->name, sym->lineDef);
1063 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1064 list2expr (sym->ival));
1067 setAstLineno (work, sym->lineDef);
1070 init = newNode (NULLOP, init, work);
1079 /*-----------------------------------------------------------------*/
1080 /* stringToSymbol - creates a symbol from a literal string */
1081 /*-----------------------------------------------------------------*/
1083 stringToSymbol (value * val)
1085 char name[SDCC_NAME_MAX + 1];
1086 static int charLbl = 0;
1089 sprintf (name, "_str_%d", charLbl++);
1090 sym = newSymbol (name, 0); /* make it @ level 0 */
1091 strcpy (sym->rname, name);
1093 /* copy the type from the value passed */
1094 sym->type = copyLinkChain (val->type);
1095 sym->etype = getSpec (sym->type);
1096 /* change to storage class & output class */
1097 SPEC_SCLS (sym->etype) = S_CODE;
1098 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1099 SPEC_STAT (sym->etype) = 1;
1100 /* make the level & block = 0 */
1101 sym->block = sym->level = 0;
1103 /* create an ival */
1104 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1109 allocVariables (sym);
1112 return symbolVal (sym);
1116 /*-----------------------------------------------------------------*/
1117 /* processBlockVars - will go thru the ast looking for block if */
1118 /* a block is found then will allocate the syms */
1119 /* will also gather the auto inits present */
1120 /*-----------------------------------------------------------------*/
1122 processBlockVars (ast * tree, int *stack, int action)
1127 /* if this is a block */
1128 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1132 if (action == ALLOCATE)
1134 *stack += allocVariables (tree->values.sym);
1135 autoInit = gatherAutoInit (tree->values.sym);
1137 /* if there are auto inits then do them */
1139 tree->left = newNode (NULLOP, autoInit, tree->left);
1141 else /* action is deallocate */
1142 deallocLocal (tree->values.sym);
1145 processBlockVars (tree->left, stack, action);
1146 processBlockVars (tree->right, stack, action);
1150 /*-------------------------------------------------------------*/
1151 /* constExprTree - returns TRUE if this tree is a constant */
1153 /*-------------------------------------------------------------*/
1154 bool constExprTree (ast *cexpr) {
1160 cexpr = decorateType (resolveSymbols (cexpr));
1162 switch (cexpr->type)
1165 if (IS_AST_LIT_VALUE(cexpr)) {
1166 // this is a literal
1169 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1170 // a function's address will never change
1173 if (IS_AST_SYM_VALUE(cexpr) &&
1174 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1175 // a symbol in code space will never change
1176 // This is only for the 'char *s="hallo"' case and will have to leave
1181 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1182 "unexpected link in expression tree\n");
1185 if (cexpr->opval.op==ARRAYINIT) {
1186 // this is a list of literals
1189 if (cexpr->opval.op=='=') {
1190 return constExprTree(cexpr->right);
1192 if (cexpr->opval.op==CAST) {
1193 // jwk: cast ignored, maybe we should throw a warning here
1194 return constExprTree(cexpr->right);
1196 if (cexpr->opval.op=='&') {
1199 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1202 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1209 /*-----------------------------------------------------------------*/
1210 /* constExprValue - returns the value of a constant expression */
1211 /* or NULL if it is not a constant expression */
1212 /*-----------------------------------------------------------------*/
1214 constExprValue (ast * cexpr, int check)
1216 cexpr = decorateType (resolveSymbols (cexpr));
1218 /* if this is not a constant then */
1219 if (!IS_LITERAL (cexpr->ftype))
1221 /* then check if this is a literal array
1223 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1224 SPEC_CVAL (cexpr->etype).v_char &&
1225 IS_ARRAY (cexpr->ftype))
1227 value *val = valFromType (cexpr->ftype);
1228 SPEC_SCLS (val->etype) = S_LITERAL;
1229 val->sym = cexpr->opval.val->sym;
1230 val->sym->type = copyLinkChain (cexpr->ftype);
1231 val->sym->etype = getSpec (val->sym->type);
1232 strcpy (val->name, cexpr->opval.val->sym->rname);
1236 /* if we are casting a literal value then */
1237 if (IS_AST_OP (cexpr) &&
1238 cexpr->opval.op == CAST &&
1239 IS_LITERAL (cexpr->left->ftype))
1240 return valCastLiteral (cexpr->ftype,
1241 floatFromVal (cexpr->left->opval.val));
1243 if (IS_AST_VALUE (cexpr))
1244 return cexpr->opval.val;
1247 werror (E_CONST_EXPECTED, "found expression");
1252 /* return the value */
1253 return cexpr->opval.val;
1257 /*-----------------------------------------------------------------*/
1258 /* isLabelInAst - will return true if a given label is found */
1259 /*-----------------------------------------------------------------*/
1261 isLabelInAst (symbol * label, ast * tree)
1263 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1266 if (IS_AST_OP (tree) &&
1267 tree->opval.op == LABEL &&
1268 isSymbolEqual (AST_SYMBOL (tree->left), label))
1271 return isLabelInAst (label, tree->right) &&
1272 isLabelInAst (label, tree->left);
1276 /*-----------------------------------------------------------------*/
1277 /* isLoopCountable - return true if the loop count can be determi- */
1278 /* -ned at compile time . */
1279 /*-----------------------------------------------------------------*/
1281 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1282 symbol ** sym, ast ** init, ast ** end)
1285 /* the loop is considered countable if the following
1286 conditions are true :-
1288 a) initExpr :- <sym> = <const>
1289 b) condExpr :- <sym> < <const1>
1290 c) loopExpr :- <sym> ++
1293 /* first check the initExpr */
1294 if (IS_AST_OP (initExpr) &&
1295 initExpr->opval.op == '=' && /* is assignment */
1296 IS_AST_SYM_VALUE (initExpr->left))
1297 { /* left is a symbol */
1299 *sym = AST_SYMBOL (initExpr->left);
1300 *init = initExpr->right;
1305 /* for now the symbol has to be of
1307 if (!IS_INTEGRAL ((*sym)->type))
1310 /* now check condExpr */
1311 if (IS_AST_OP (condExpr))
1314 switch (condExpr->opval.op)
1317 if (IS_AST_SYM_VALUE (condExpr->left) &&
1318 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1319 IS_AST_LIT_VALUE (condExpr->right))
1321 *end = condExpr->right;
1327 if (IS_AST_OP (condExpr->left) &&
1328 condExpr->left->opval.op == '>' &&
1329 IS_AST_LIT_VALUE (condExpr->left->right) &&
1330 IS_AST_SYM_VALUE (condExpr->left->left) &&
1331 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1334 *end = newNode ('+', condExpr->left->right,
1335 newAst_VALUE (constVal ("1")));
1346 /* check loop expression is of the form <sym>++ */
1347 if (!IS_AST_OP (loopExpr))
1350 /* check if <sym> ++ */
1351 if (loopExpr->opval.op == INC_OP)
1357 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1358 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1365 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1366 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1374 if (loopExpr->opval.op == ADD_ASSIGN)
1377 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1378 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1379 IS_AST_LIT_VALUE (loopExpr->right) &&
1380 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1388 /*-----------------------------------------------------------------*/
1389 /* astHasVolatile - returns true if ast contains any volatile */
1390 /*-----------------------------------------------------------------*/
1392 astHasVolatile (ast * tree)
1397 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1400 if (IS_AST_OP (tree))
1401 return astHasVolatile (tree->left) ||
1402 astHasVolatile (tree->right);
1407 /*-----------------------------------------------------------------*/
1408 /* astHasPointer - return true if the ast contains any ptr variable */
1409 /*-----------------------------------------------------------------*/
1411 astHasPointer (ast * tree)
1416 if (IS_AST_LINK (tree))
1419 /* if we hit an array expression then check
1420 only the left side */
1421 if (IS_AST_OP (tree) && tree->opval.op == '[')
1422 return astHasPointer (tree->left);
1424 if (IS_AST_VALUE (tree))
1425 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1427 return astHasPointer (tree->left) ||
1428 astHasPointer (tree->right);
1432 /*-----------------------------------------------------------------*/
1433 /* astHasSymbol - return true if the ast has the given symbol */
1434 /*-----------------------------------------------------------------*/
1436 astHasSymbol (ast * tree, symbol * sym)
1438 if (!tree || IS_AST_LINK (tree))
1441 if (IS_AST_VALUE (tree))
1443 if (IS_AST_SYM_VALUE (tree))
1444 return isSymbolEqual (AST_SYMBOL (tree), sym);
1449 return astHasSymbol (tree->left, sym) ||
1450 astHasSymbol (tree->right, sym);
1453 /*-----------------------------------------------------------------*/
1454 /* astHasDeref - return true if the ast has an indirect access */
1455 /*-----------------------------------------------------------------*/
1457 astHasDeref (ast * tree)
1459 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1462 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1464 return astHasDeref (tree->left) || astHasDeref (tree->right);
1467 /*-----------------------------------------------------------------*/
1468 /* isConformingBody - the loop body has to conform to a set of rules */
1469 /* for the loop to be considered reversible read on for rules */
1470 /*-----------------------------------------------------------------*/
1472 isConformingBody (ast * pbody, symbol * sym, ast * body)
1475 /* we are going to do a pre-order traversal of the
1476 tree && check for the following conditions. (essentially
1477 a set of very shallow tests )
1478 a) the sym passed does not participate in
1479 any arithmetic operation
1480 b) There are no function calls
1481 c) all jumps are within the body
1482 d) address of loop control variable not taken
1483 e) if an assignment has a pointer on the
1484 left hand side make sure right does not have
1485 loop control variable */
1487 /* if we reach the end or a leaf then true */
1488 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1492 /* if anything else is "volatile" */
1493 if (IS_VOLATILE (TETYPE (pbody)))
1496 /* we will walk the body in a pre-order traversal for
1498 switch (pbody->opval.op)
1500 /*------------------------------------------------------------------*/
1502 return isConformingBody (pbody->right, sym, body);
1504 /*------------------------------------------------------------------*/
1509 /*------------------------------------------------------------------*/
1510 case INC_OP: /* incerement operator unary so left only */
1513 /* sure we are not sym is not modified */
1515 IS_AST_SYM_VALUE (pbody->left) &&
1516 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1520 IS_AST_SYM_VALUE (pbody->right) &&
1521 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1526 /*------------------------------------------------------------------*/
1528 case '*': /* can be unary : if right is null then unary operation */
1533 /* if right is NULL then unary operation */
1534 /*------------------------------------------------------------------*/
1535 /*----------------------------*/
1537 /*----------------------------*/
1540 if (IS_AST_SYM_VALUE (pbody->left) &&
1541 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1544 return isConformingBody (pbody->left, sym, body);
1548 if (astHasSymbol (pbody->left, sym) ||
1549 astHasSymbol (pbody->right, sym))
1554 /*------------------------------------------------------------------*/
1562 if (IS_AST_SYM_VALUE (pbody->left) &&
1563 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1566 if (IS_AST_SYM_VALUE (pbody->right) &&
1567 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1570 return isConformingBody (pbody->left, sym, body) &&
1571 isConformingBody (pbody->right, sym, body);
1578 if (IS_AST_SYM_VALUE (pbody->left) &&
1579 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1581 return isConformingBody (pbody->left, sym, body);
1583 /*------------------------------------------------------------------*/
1595 case SIZEOF: /* evaluate wihout code generation */
1597 return isConformingBody (pbody->left, sym, body) &&
1598 isConformingBody (pbody->right, sym, body);
1600 /*------------------------------------------------------------------*/
1603 /* if left has a pointer & right has loop
1604 control variable then we cannot */
1605 if (astHasPointer (pbody->left) &&
1606 astHasSymbol (pbody->right, sym))
1608 if (astHasVolatile (pbody->left))
1611 if (IS_AST_SYM_VALUE (pbody->left) &&
1612 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1615 if (astHasVolatile (pbody->left))
1618 if (astHasDeref(pbody->right)) return FALSE;
1620 return isConformingBody (pbody->left, sym, body) &&
1621 isConformingBody (pbody->right, sym, body);
1632 assert ("Parser should not have generated this\n");
1634 /*------------------------------------------------------------------*/
1635 /*----------------------------*/
1636 /* comma operator */
1637 /*----------------------------*/
1639 return isConformingBody (pbody->left, sym, body) &&
1640 isConformingBody (pbody->right, sym, body);
1642 /*------------------------------------------------------------------*/
1643 /*----------------------------*/
1645 /*----------------------------*/
1647 /* if local & not passed as paramater then ok */
1648 if (sym->level && !astHasSymbol(pbody->right,sym))
1652 /*------------------------------------------------------------------*/
1653 /*----------------------------*/
1654 /* return statement */
1655 /*----------------------------*/
1660 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1665 if (astHasSymbol (pbody->left, sym))
1672 return isConformingBody (pbody->left, sym, body) &&
1673 isConformingBody (pbody->right, sym, body);
1679 /*-----------------------------------------------------------------*/
1680 /* isLoopReversible - takes a for loop as input && returns true */
1681 /* if the for loop is reversible. If yes will set the value of */
1682 /* the loop control var & init value & termination value */
1683 /*-----------------------------------------------------------------*/
1685 isLoopReversible (ast * loop, symbol ** loopCntrl,
1686 ast ** init, ast ** end)
1688 /* if option says don't do it then don't */
1689 if (optimize.noLoopReverse)
1691 /* there are several tests to determine this */
1693 /* for loop has to be of the form
1694 for ( <sym> = <const1> ;
1695 [<sym> < <const2>] ;
1696 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1698 if (!isLoopCountable (AST_FOR (loop, initExpr),
1699 AST_FOR (loop, condExpr),
1700 AST_FOR (loop, loopExpr),
1701 loopCntrl, init, end))
1704 /* now do some serious checking on the body of the loop
1707 return isConformingBody (loop->left, *loopCntrl, loop->left);
1711 /*-----------------------------------------------------------------*/
1712 /* replLoopSym - replace the loop sym by loop sym -1 */
1713 /*-----------------------------------------------------------------*/
1715 replLoopSym (ast * body, symbol * sym)
1718 if (!body || IS_AST_LINK (body))
1721 if (IS_AST_SYM_VALUE (body))
1724 if (isSymbolEqual (AST_SYMBOL (body), sym))
1728 body->opval.op = '-';
1729 body->left = newAst_VALUE (symbolVal (sym));
1730 body->right = newAst_VALUE (constVal ("1"));
1738 replLoopSym (body->left, sym);
1739 replLoopSym (body->right, sym);
1743 /*-----------------------------------------------------------------*/
1744 /* reverseLoop - do the actual loop reversal */
1745 /*-----------------------------------------------------------------*/
1747 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1751 /* create the following tree
1756 if (sym) goto for_continue ;
1759 /* put it together piece by piece */
1760 rloop = newNode (NULLOP,
1761 createIf (newAst_VALUE (symbolVal (sym)),
1763 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1766 newAst_VALUE (symbolVal (sym)),
1769 replLoopSym (loop->left, sym);
1771 rloop = newNode (NULLOP,
1773 newAst_VALUE (symbolVal (sym)),
1774 newNode ('-', end, init)),
1775 createLabel (AST_FOR (loop, continueLabel),
1779 newNode (SUB_ASSIGN,
1780 newAst_VALUE (symbolVal (sym)),
1781 newAst_VALUE (constVal ("1"))),
1784 return decorateType (rloop);
1788 /*-----------------------------------------------------------------*/
1789 /* decorateType - compute type for this tree also does type cheking */
1790 /* this is done bottom up, since type have to flow upwards */
1791 /* it also does constant folding, and paramater checking */
1792 /*-----------------------------------------------------------------*/
1794 decorateType (ast * tree)
1802 /* if already has type then do nothing */
1803 if (tree->decorated)
1806 tree->decorated = 1;
1808 /* print the line */
1809 /* if not block & function */
1810 if (tree->type == EX_OP &&
1811 (tree->opval.op != FUNCTION &&
1812 tree->opval.op != BLOCK &&
1813 tree->opval.op != NULLOP))
1815 filename = tree->filename;
1816 lineno = tree->lineno;
1819 /* if any child is an error | this one is an error do nothing */
1820 if (tree->isError ||
1821 (tree->left && tree->left->isError) ||
1822 (tree->right && tree->right->isError))
1825 /*------------------------------------------------------------------*/
1826 /*----------------------------*/
1827 /* leaf has been reached */
1828 /*----------------------------*/
1829 /* if this is of type value */
1830 /* just get the type */
1831 if (tree->type == EX_VALUE)
1834 if (IS_LITERAL (tree->opval.val->etype))
1837 /* if this is a character array then declare it */
1838 if (IS_ARRAY (tree->opval.val->type))
1839 tree->opval.val = stringToSymbol (tree->opval.val);
1841 /* otherwise just copy the type information */
1842 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1846 if (tree->opval.val->sym)
1848 /* if the undefined flag is set then give error message */
1849 if (tree->opval.val->sym->undefined)
1851 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1853 TTYPE (tree) = TETYPE (tree) =
1854 tree->opval.val->type = tree->opval.val->sym->type =
1855 tree->opval.val->etype = tree->opval.val->sym->etype =
1856 copyLinkChain (INTTYPE);
1861 /* if impilicit i.e. struct/union member then no type */
1862 if (tree->opval.val->sym->implicit)
1863 TTYPE (tree) = TETYPE (tree) = NULL;
1868 /* else copy the type */
1869 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1871 /* and mark it as referenced */
1872 tree->opval.val->sym->isref = 1;
1880 /* if type link for the case of cast */
1881 if (tree->type == EX_LINK)
1883 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1890 dtl = decorateType (tree->left);
1891 /* delay right side for '?' operator since conditional macro expansions might
1893 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1895 /* this is to take care of situations
1896 when the tree gets rewritten */
1897 if (dtl != tree->left)
1899 if (dtr != tree->right)
1903 /* depending on type of operator do */
1905 switch (tree->opval.op)
1907 /*------------------------------------------------------------------*/
1908 /*----------------------------*/
1910 /*----------------------------*/
1913 /* determine which is the array & which the index */
1914 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1917 ast *tempTree = tree->left;
1918 tree->left = tree->right;
1919 tree->right = tempTree;
1922 /* first check if this is a array or a pointer */
1923 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1925 werror (E_NEED_ARRAY_PTR, "[]");
1926 goto errorTreeReturn;
1929 /* check if the type of the idx */
1930 if (!IS_INTEGRAL (RTYPE (tree)))
1932 werror (E_IDX_NOT_INT);
1933 goto errorTreeReturn;
1936 /* if the left is an rvalue then error */
1939 werror (E_LVALUE_REQUIRED, "array access");
1940 goto errorTreeReturn;
1943 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1944 if (IS_PTR(LTYPE(tree))) {
1945 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1949 /*------------------------------------------------------------------*/
1950 /*----------------------------*/
1952 /*----------------------------*/
1954 /* if this is not a structure */
1955 if (!IS_STRUCT (LTYPE (tree)))
1957 werror (E_STRUCT_UNION, ".");
1958 goto errorTreeReturn;
1960 TTYPE (tree) = structElemType (LTYPE (tree),
1961 (tree->right->type == EX_VALUE ?
1962 tree->right->opval.val : NULL));
1963 TETYPE (tree) = getSpec (TTYPE (tree));
1966 /*------------------------------------------------------------------*/
1967 /*----------------------------*/
1968 /* struct/union pointer */
1969 /*----------------------------*/
1971 /* if not pointer to a structure */
1972 if (!IS_PTR (LTYPE (tree)))
1974 werror (E_PTR_REQD);
1975 goto errorTreeReturn;
1978 if (!IS_STRUCT (LTYPE (tree)->next))
1980 werror (E_STRUCT_UNION, "->");
1981 goto errorTreeReturn;
1984 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1985 (tree->right->type == EX_VALUE ?
1986 tree->right->opval.val : NULL));
1987 TETYPE (tree) = getSpec (TTYPE (tree));
1989 /* adjust the storage class */
1990 switch (DCL_TYPE(tree->left->ftype)) {
1994 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
1997 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2002 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2005 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2008 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2017 /*------------------------------------------------------------------*/
2018 /*----------------------------*/
2019 /* ++/-- operation */
2020 /*----------------------------*/
2021 case INC_OP: /* incerement operator unary so left only */
2024 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2025 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2026 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2027 werror (E_CODE_WRITE, "++/--");
2036 /*------------------------------------------------------------------*/
2037 /*----------------------------*/
2039 /*----------------------------*/
2040 case '&': /* can be unary */
2041 /* if right is NULL then unary operation */
2042 if (tree->right) /* not an unary operation */
2045 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2047 werror (E_BITWISE_OP);
2048 werror (W_CONTINUE, "left & right types are ");
2049 printTypeChain (LTYPE (tree), stderr);
2050 fprintf (stderr, ",");
2051 printTypeChain (RTYPE (tree), stderr);
2052 fprintf (stderr, "\n");
2053 goto errorTreeReturn;
2056 /* if they are both literal */
2057 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2059 tree->type = EX_VALUE;
2060 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2061 valFromType (RETYPE (tree)), '&');
2063 tree->right = tree->left = NULL;
2064 TETYPE (tree) = tree->opval.val->etype;
2065 TTYPE (tree) = tree->opval.val->type;
2069 /* see if this is a GETHBIT operation if yes
2072 ast *otree = optimizeGetHbit (tree);
2075 return decorateType (otree);
2079 computeType (LTYPE (tree), RTYPE (tree));
2080 TETYPE (tree) = getSpec (TTYPE (tree));
2082 LRVAL (tree) = RRVAL (tree) = 1;
2086 /*------------------------------------------------------------------*/
2087 /*----------------------------*/
2089 /*----------------------------*/
2091 p->class = DECLARATOR;
2092 /* if bit field then error */
2093 if (IS_BITVAR (tree->left->etype))
2095 werror (E_ILLEGAL_ADDR, "address of bit variable");
2096 goto errorTreeReturn;
2099 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2101 werror (E_ILLEGAL_ADDR, "address of register variable");
2102 goto errorTreeReturn;
2105 if (IS_FUNC (LTYPE (tree)))
2107 werror (E_ILLEGAL_ADDR, "address of function");
2108 goto errorTreeReturn;
2111 if (IS_LITERAL(LTYPE(tree)))
2113 werror (E_ILLEGAL_ADDR, "address of literal");
2114 goto errorTreeReturn;
2119 werror (E_LVALUE_REQUIRED, "address of");
2120 goto errorTreeReturn;
2122 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2124 DCL_TYPE (p) = CPOINTER;
2125 DCL_PTR_CONST (p) = port->mem.code_ro;
2127 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2128 DCL_TYPE (p) = FPOINTER;
2129 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2130 DCL_TYPE (p) = PPOINTER;
2131 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2132 DCL_TYPE (p) = IPOINTER;
2133 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2134 DCL_TYPE (p) = EEPPOINTER;
2135 else if (SPEC_OCLS(tree->left->etype))
2136 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2138 DCL_TYPE (p) = POINTER;
2140 if (IS_AST_SYM_VALUE (tree->left))
2142 AST_SYMBOL (tree->left)->addrtaken = 1;
2143 AST_SYMBOL (tree->left)->allocreq = 1;
2146 p->next = LTYPE (tree);
2148 TETYPE (tree) = getSpec (TTYPE (tree));
2149 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2150 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2155 /*------------------------------------------------------------------*/
2156 /*----------------------------*/
2158 /*----------------------------*/
2160 /* if the rewrite succeeds then don't go any furthur */
2162 ast *wtree = optimizeRRCRLC (tree);
2164 return decorateType (wtree);
2166 /*------------------------------------------------------------------*/
2167 /*----------------------------*/
2169 /*----------------------------*/
2171 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2173 werror (E_BITWISE_OP);
2174 werror (W_CONTINUE, "left & right types are ");
2175 printTypeChain (LTYPE (tree), stderr);
2176 fprintf (stderr, ",");
2177 printTypeChain (RTYPE (tree), stderr);
2178 fprintf (stderr, "\n");
2179 goto errorTreeReturn;
2182 /* if they are both literal then */
2183 /* rewrite the tree */
2184 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2186 tree->type = EX_VALUE;
2187 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2188 valFromType (RETYPE (tree)),
2190 tree->right = tree->left = NULL;
2191 TETYPE (tree) = tree->opval.val->etype;
2192 TTYPE (tree) = tree->opval.val->type;
2195 LRVAL (tree) = RRVAL (tree) = 1;
2196 TETYPE (tree) = getSpec (TTYPE (tree) =
2197 computeType (LTYPE (tree),
2200 /*------------------------------------------------------------------*/
2201 /*----------------------------*/
2203 /*----------------------------*/
2205 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2207 werror (E_INVALID_OP, "divide");
2208 goto errorTreeReturn;
2210 /* if they are both literal then */
2211 /* rewrite the tree */
2212 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2214 tree->type = EX_VALUE;
2215 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2216 valFromType (RETYPE (tree)));
2217 tree->right = tree->left = NULL;
2218 TETYPE (tree) = getSpec (TTYPE (tree) =
2219 tree->opval.val->type);
2222 LRVAL (tree) = RRVAL (tree) = 1;
2223 TETYPE (tree) = getSpec (TTYPE (tree) =
2224 computeType (LTYPE (tree),
2228 /*------------------------------------------------------------------*/
2229 /*----------------------------*/
2231 /*----------------------------*/
2233 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2235 werror (E_BITWISE_OP);
2236 werror (W_CONTINUE, "left & right types are ");
2237 printTypeChain (LTYPE (tree), stderr);
2238 fprintf (stderr, ",");
2239 printTypeChain (RTYPE (tree), stderr);
2240 fprintf (stderr, "\n");
2241 goto errorTreeReturn;
2243 /* if they are both literal then */
2244 /* rewrite the tree */
2245 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2247 tree->type = EX_VALUE;
2248 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2249 valFromType (RETYPE (tree)));
2250 tree->right = tree->left = NULL;
2251 TETYPE (tree) = getSpec (TTYPE (tree) =
2252 tree->opval.val->type);
2255 LRVAL (tree) = RRVAL (tree) = 1;
2256 TETYPE (tree) = getSpec (TTYPE (tree) =
2257 computeType (LTYPE (tree),
2261 /*------------------------------------------------------------------*/
2262 /*----------------------------*/
2263 /* address dereference */
2264 /*----------------------------*/
2265 case '*': /* can be unary : if right is null then unary operation */
2268 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2270 werror (E_PTR_REQD);
2271 goto errorTreeReturn;
2276 werror (E_LVALUE_REQUIRED, "pointer deref");
2277 goto errorTreeReturn;
2279 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2280 LTYPE (tree)->next : NULL);
2281 TETYPE (tree) = getSpec (TTYPE (tree));
2282 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2286 /*------------------------------------------------------------------*/
2287 /*----------------------------*/
2288 /* multiplication */
2289 /*----------------------------*/
2290 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2292 werror (E_INVALID_OP, "multiplication");
2293 goto errorTreeReturn;
2296 /* if they are both literal then */
2297 /* rewrite the tree */
2298 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2300 tree->type = EX_VALUE;
2301 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2302 valFromType (RETYPE (tree)));
2303 tree->right = tree->left = NULL;
2304 TETYPE (tree) = getSpec (TTYPE (tree) =
2305 tree->opval.val->type);
2309 /* if left is a literal exchange left & right */
2310 if (IS_LITERAL (LTYPE (tree)))
2312 ast *tTree = tree->left;
2313 tree->left = tree->right;
2314 tree->right = tTree;
2317 LRVAL (tree) = RRVAL (tree) = 1;
2318 /* promote result to int if left & right are char
2319 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2320 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2321 TETYPE (tree) = getSpec (TTYPE (tree) =
2322 computeType (LTYPE (tree),
2324 SPEC_NOUN(TETYPE(tree)) = V_INT;
2326 TETYPE (tree) = getSpec (TTYPE (tree) =
2327 computeType (LTYPE (tree),
2332 /*------------------------------------------------------------------*/
2333 /*----------------------------*/
2334 /* unary '+' operator */
2335 /*----------------------------*/
2340 if (!IS_INTEGRAL (LTYPE (tree)))
2342 werror (E_UNARY_OP, '+');
2343 goto errorTreeReturn;
2346 /* if left is a literal then do it */
2347 if (IS_LITERAL (LTYPE (tree)))
2349 tree->type = EX_VALUE;
2350 tree->opval.val = valFromType (LETYPE (tree));
2352 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2356 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2360 /*------------------------------------------------------------------*/
2361 /*----------------------------*/
2363 /*----------------------------*/
2365 /* this is not a unary operation */
2366 /* if both pointers then problem */
2367 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2368 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2370 werror (E_PTR_PLUS_PTR);
2371 goto errorTreeReturn;
2374 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2375 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2377 werror (E_PLUS_INVALID, "+");
2378 goto errorTreeReturn;
2381 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2382 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2384 werror (E_PLUS_INVALID, "+");
2385 goto errorTreeReturn;
2387 /* if they are both literal then */
2388 /* rewrite the tree */
2389 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2391 tree->type = EX_VALUE;
2392 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2393 valFromType (RETYPE (tree)));
2394 tree->right = tree->left = NULL;
2395 TETYPE (tree) = getSpec (TTYPE (tree) =
2396 tree->opval.val->type);
2400 /* if the right is a pointer or left is a literal
2401 xchange left & right */
2402 if (IS_ARRAY (RTYPE (tree)) ||
2403 IS_PTR (RTYPE (tree)) ||
2404 IS_LITERAL (LTYPE (tree)))
2406 ast *tTree = tree->left;
2407 tree->left = tree->right;
2408 tree->right = tTree;
2411 LRVAL (tree) = RRVAL (tree) = 1;
2412 /* if the left is a pointer */
2413 if (IS_PTR (LTYPE (tree)))
2414 TETYPE (tree) = getSpec (TTYPE (tree) =
2417 TETYPE (tree) = getSpec (TTYPE (tree) =
2418 computeType (LTYPE (tree),
2422 /*------------------------------------------------------------------*/
2423 /*----------------------------*/
2425 /*----------------------------*/
2426 case '-': /* can be unary */
2427 /* if right is null then unary */
2431 if (!IS_ARITHMETIC (LTYPE (tree)))
2433 werror (E_UNARY_OP, tree->opval.op);
2434 goto errorTreeReturn;
2437 /* if left is a literal then do it */
2438 if (IS_LITERAL (LTYPE (tree)))
2440 tree->type = EX_VALUE;
2441 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2443 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2444 SPEC_USIGN(TETYPE(tree)) = 0;
2448 TTYPE (tree) = LTYPE (tree);
2452 /*------------------------------------------------------------------*/
2453 /*----------------------------*/
2455 /*----------------------------*/
2457 if (!(IS_PTR (LTYPE (tree)) ||
2458 IS_ARRAY (LTYPE (tree)) ||
2459 IS_ARITHMETIC (LTYPE (tree))))
2461 werror (E_PLUS_INVALID, "-");
2462 goto errorTreeReturn;
2465 if (!(IS_PTR (RTYPE (tree)) ||
2466 IS_ARRAY (RTYPE (tree)) ||
2467 IS_ARITHMETIC (RTYPE (tree))))
2469 werror (E_PLUS_INVALID, "-");
2470 goto errorTreeReturn;
2473 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2474 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2475 IS_INTEGRAL (RTYPE (tree))))
2477 werror (E_PLUS_INVALID, "-");
2478 goto errorTreeReturn;
2481 /* if they are both literal then */
2482 /* rewrite the tree */
2483 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2485 tree->type = EX_VALUE;
2486 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2487 valFromType (RETYPE (tree)));
2488 tree->right = tree->left = NULL;
2489 TETYPE (tree) = getSpec (TTYPE (tree) =
2490 tree->opval.val->type);
2494 /* if the left & right are equal then zero */
2495 if (isAstEqual (tree->left, tree->right))
2497 tree->type = EX_VALUE;
2498 tree->left = tree->right = NULL;
2499 tree->opval.val = constVal ("0");
2500 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2504 /* if both of them are pointers or arrays then */
2505 /* the result is going to be an integer */
2506 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2507 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2508 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2510 /* if only the left is a pointer */
2511 /* then result is a pointer */
2512 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2513 TETYPE (tree) = getSpec (TTYPE (tree) =
2516 TETYPE (tree) = getSpec (TTYPE (tree) =
2517 computeType (LTYPE (tree),
2519 LRVAL (tree) = RRVAL (tree) = 1;
2522 /*------------------------------------------------------------------*/
2523 /*----------------------------*/
2525 /*----------------------------*/
2527 /* can be only integral type */
2528 if (!IS_INTEGRAL (LTYPE (tree)))
2530 werror (E_UNARY_OP, tree->opval.op);
2531 goto errorTreeReturn;
2534 /* if left is a literal then do it */
2535 if (IS_LITERAL (LTYPE (tree)))
2537 tree->type = EX_VALUE;
2538 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2540 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2544 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2547 /*------------------------------------------------------------------*/
2548 /*----------------------------*/
2550 /*----------------------------*/
2552 /* can be pointer */
2553 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2554 !IS_PTR (LTYPE (tree)) &&
2555 !IS_ARRAY (LTYPE (tree)))
2557 werror (E_UNARY_OP, tree->opval.op);
2558 goto errorTreeReturn;
2561 /* if left is a literal then do it */
2562 if (IS_LITERAL (LTYPE (tree)))
2564 tree->type = EX_VALUE;
2565 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2567 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2571 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2574 /*------------------------------------------------------------------*/
2575 /*----------------------------*/
2577 /*----------------------------*/
2580 TTYPE (tree) = LTYPE (tree);
2581 TETYPE (tree) = LETYPE (tree);
2585 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2590 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2592 werror (E_SHIFT_OP_INVALID);
2593 werror (W_CONTINUE, "left & right types are ");
2594 printTypeChain (LTYPE (tree), stderr);
2595 fprintf (stderr, ",");
2596 printTypeChain (RTYPE (tree), stderr);
2597 fprintf (stderr, "\n");
2598 goto errorTreeReturn;
2601 /* if they are both literal then */
2602 /* rewrite the tree */
2603 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2605 tree->type = EX_VALUE;
2606 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2607 valFromType (RETYPE (tree)),
2608 (tree->opval.op == LEFT_OP ? 1 : 0));
2609 tree->right = tree->left = NULL;
2610 TETYPE (tree) = getSpec (TTYPE (tree) =
2611 tree->opval.val->type);
2614 /* if only the right side is a literal & we are
2615 shifting more than size of the left operand then zero */
2616 if (IS_LITERAL (RTYPE (tree)) &&
2617 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2618 (getSize (LTYPE (tree)) * 8))
2620 werror (W_SHIFT_CHANGED,
2621 (tree->opval.op == LEFT_OP ? "left" : "right"));
2622 tree->type = EX_VALUE;
2623 tree->left = tree->right = NULL;
2624 tree->opval.val = constVal ("0");
2625 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2628 LRVAL (tree) = RRVAL (tree) = 1;
2629 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2631 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2635 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2639 /*------------------------------------------------------------------*/
2640 /*----------------------------*/
2642 /*----------------------------*/
2643 case CAST: /* change the type */
2644 /* cannot cast to an aggregate type */
2645 if (IS_AGGREGATE (LTYPE (tree)))
2647 werror (E_CAST_ILLEGAL);
2648 goto errorTreeReturn;
2651 /* make sure the type is complete and sane */
2652 checkTypeSanity(LETYPE(tree), "(cast)");
2655 /* if the right is a literal replace the tree */
2656 if (IS_LITERAL (RETYPE (tree))) {
2657 if (!IS_PTR (LTYPE (tree))) {
2658 tree->type = EX_VALUE;
2660 valCastLiteral (LTYPE (tree),
2661 floatFromVal (valFromType (RETYPE (tree))));
2664 TTYPE (tree) = tree->opval.val->type;
2665 tree->values.literalFromCast = 1;
2666 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2667 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2668 sym_link *rest = LTYPE(tree)->next;
2669 werror(W_LITERAL_GENERIC);
2670 TTYPE(tree) = newLink();
2671 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2672 TTYPE(tree)->next = rest;
2673 tree->left->opval.lnk = TTYPE(tree);
2676 TTYPE (tree) = LTYPE (tree);
2680 TTYPE (tree) = LTYPE (tree);
2684 /* if pointer to struct then check names */
2685 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2686 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2687 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2688 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2690 /* if the right is a literal replace the tree */
2691 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2692 tree->type = EX_VALUE;
2694 valCastLiteral (LTYPE (tree),
2695 floatFromVal (valFromType (RETYPE (tree))));
2698 TTYPE (tree) = tree->opval.val->type;
2699 tree->values.literalFromCast = 1;
2701 TTYPE (tree) = LTYPE (tree);
2705 TETYPE (tree) = getSpec (TTYPE (tree));
2709 /*------------------------------------------------------------------*/
2710 /*----------------------------*/
2711 /* logical &&, || */
2712 /*----------------------------*/
2715 /* each must me arithmetic type or be a pointer */
2716 if (!IS_PTR (LTYPE (tree)) &&
2717 !IS_ARRAY (LTYPE (tree)) &&
2718 !IS_INTEGRAL (LTYPE (tree)))
2720 werror (E_COMPARE_OP);
2721 goto errorTreeReturn;
2724 if (!IS_PTR (RTYPE (tree)) &&
2725 !IS_ARRAY (RTYPE (tree)) &&
2726 !IS_INTEGRAL (RTYPE (tree)))
2728 werror (E_COMPARE_OP);
2729 goto errorTreeReturn;
2731 /* if they are both literal then */
2732 /* rewrite the tree */
2733 if (IS_LITERAL (RTYPE (tree)) &&
2734 IS_LITERAL (LTYPE (tree)))
2736 tree->type = EX_VALUE;
2737 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2738 valFromType (RETYPE (tree)),
2740 tree->right = tree->left = NULL;
2741 TETYPE (tree) = getSpec (TTYPE (tree) =
2742 tree->opval.val->type);
2745 LRVAL (tree) = RRVAL (tree) = 1;
2746 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2749 /*------------------------------------------------------------------*/
2750 /*----------------------------*/
2751 /* comparison operators */
2752 /*----------------------------*/
2760 ast *lt = optimizeCompare (tree);
2766 /* if they are pointers they must be castable */
2767 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2769 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2771 werror (E_COMPARE_OP);
2772 fprintf (stderr, "comparing type ");
2773 printTypeChain (LTYPE (tree), stderr);
2774 fprintf (stderr, "to type ");
2775 printTypeChain (RTYPE (tree), stderr);
2776 fprintf (stderr, "\n");
2777 goto errorTreeReturn;
2780 /* else they should be promotable to one another */
2783 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2784 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2786 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2788 werror (E_COMPARE_OP);
2789 fprintf (stderr, "comparing type ");
2790 printTypeChain (LTYPE (tree), stderr);
2791 fprintf (stderr, "to type ");
2792 printTypeChain (RTYPE (tree), stderr);
2793 fprintf (stderr, "\n");
2794 goto errorTreeReturn;
2797 /* if unsigned value < 0 then always false */
2798 /* if (unsigned value) > 0 then (unsigned value) */
2799 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2800 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2802 if (tree->opval.op == '<') {
2805 if (tree->opval.op == '>') {
2809 /* if they are both literal then */
2810 /* rewrite the tree */
2811 if (IS_LITERAL (RTYPE (tree)) &&
2812 IS_LITERAL (LTYPE (tree)))
2814 tree->type = EX_VALUE;
2815 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2816 valFromType (RETYPE (tree)),
2818 tree->right = tree->left = NULL;
2819 TETYPE (tree) = getSpec (TTYPE (tree) =
2820 tree->opval.val->type);
2823 LRVAL (tree) = RRVAL (tree) = 1;
2824 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2827 /*------------------------------------------------------------------*/
2828 /*----------------------------*/
2830 /*----------------------------*/
2831 case SIZEOF: /* evaluate wihout code generation */
2832 /* change the type to a integer */
2833 tree->type = EX_VALUE;
2834 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2835 tree->opval.val = constVal (buffer);
2836 tree->right = tree->left = NULL;
2837 TETYPE (tree) = getSpec (TTYPE (tree) =
2838 tree->opval.val->type);
2841 /*------------------------------------------------------------------*/
2842 /*----------------------------*/
2844 /*----------------------------*/
2846 /* return typeof enum value */
2847 tree->type = EX_VALUE;
2850 if (IS_SPEC(tree->right->ftype)) {
2851 switch (SPEC_NOUN(tree->right->ftype)) {
2853 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2854 else typeofv = TYPEOF_INT;
2857 typeofv = TYPEOF_FLOAT;
2860 typeofv = TYPEOF_CHAR;
2863 typeofv = TYPEOF_VOID;
2866 typeofv = TYPEOF_STRUCT;
2869 typeofv = TYPEOF_BIT;
2872 typeofv = TYPEOF_SBIT;
2878 switch (DCL_TYPE(tree->right->ftype)) {
2880 typeofv = TYPEOF_POINTER;
2883 typeofv = TYPEOF_FPOINTER;
2886 typeofv = TYPEOF_CPOINTER;
2889 typeofv = TYPEOF_GPOINTER;
2892 typeofv = TYPEOF_PPOINTER;
2895 typeofv = TYPEOF_IPOINTER;
2898 typeofv = TYPEOF_ARRAY;
2901 typeofv = TYPEOF_FUNCTION;
2907 sprintf (buffer, "%d", typeofv);
2908 tree->opval.val = constVal (buffer);
2909 tree->right = tree->left = NULL;
2910 TETYPE (tree) = getSpec (TTYPE (tree) =
2911 tree->opval.val->type);
2914 /*------------------------------------------------------------------*/
2915 /*----------------------------*/
2916 /* conditional operator '?' */
2917 /*----------------------------*/
2919 /* the type is value of the colon operator (on the right) */
2920 assert(IS_COLON_OP(tree->right));
2921 /* if already known then replace the tree : optimizer will do it
2922 but faster to do it here */
2923 if (IS_LITERAL (LTYPE(tree))) {
2924 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2925 return decorateType(tree->right->left) ;
2927 return decorateType(tree->right->right) ;
2930 tree->right = decorateType(tree->right);
2931 TTYPE (tree) = RTYPE(tree);
2932 TETYPE (tree) = getSpec (TTYPE (tree));
2937 /* if they don't match we have a problem */
2938 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2940 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2941 goto errorTreeReturn;
2944 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2945 TETYPE (tree) = getSpec (TTYPE (tree));
2949 /*------------------------------------------------------------------*/
2950 /*----------------------------*/
2951 /* assignment operators */
2952 /*----------------------------*/
2955 /* for these it must be both must be integral */
2956 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2957 !IS_ARITHMETIC (RTYPE (tree)))
2959 werror (E_OPS_INTEGRAL);
2960 goto errorTreeReturn;
2963 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2965 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2966 werror (E_CODE_WRITE, " ");
2970 werror (E_LVALUE_REQUIRED, "*= or /=");
2971 goto errorTreeReturn;
2982 /* for these it must be both must be integral */
2983 if (!IS_INTEGRAL (LTYPE (tree)) ||
2984 !IS_INTEGRAL (RTYPE (tree)))
2986 werror (E_OPS_INTEGRAL);
2987 goto errorTreeReturn;
2990 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2992 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2993 werror (E_CODE_WRITE, " ");
2997 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2998 goto errorTreeReturn;
3004 /*------------------------------------------------------------------*/
3005 /*----------------------------*/
3007 /*----------------------------*/
3009 if (!(IS_PTR (LTYPE (tree)) ||
3010 IS_ARITHMETIC (LTYPE (tree))))
3012 werror (E_PLUS_INVALID, "-=");
3013 goto errorTreeReturn;
3016 if (!(IS_PTR (RTYPE (tree)) ||
3017 IS_ARITHMETIC (RTYPE (tree))))
3019 werror (E_PLUS_INVALID, "-=");
3020 goto errorTreeReturn;
3023 TETYPE (tree) = getSpec (TTYPE (tree) =
3024 computeType (LTYPE (tree),
3027 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3028 werror (E_CODE_WRITE, " ");
3032 werror (E_LVALUE_REQUIRED, "-=");
3033 goto errorTreeReturn;
3039 /*------------------------------------------------------------------*/
3040 /*----------------------------*/
3042 /*----------------------------*/
3044 /* this is not a unary operation */
3045 /* if both pointers then problem */
3046 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3048 werror (E_PTR_PLUS_PTR);
3049 goto errorTreeReturn;
3052 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3054 werror (E_PLUS_INVALID, "+=");
3055 goto errorTreeReturn;
3058 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3060 werror (E_PLUS_INVALID, "+=");
3061 goto errorTreeReturn;
3064 TETYPE (tree) = getSpec (TTYPE (tree) =
3065 computeType (LTYPE (tree),
3068 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3069 werror (E_CODE_WRITE, " ");
3073 werror (E_LVALUE_REQUIRED, "+=");
3074 goto errorTreeReturn;
3077 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3078 tree->opval.op = '=';
3082 /*------------------------------------------------------------------*/
3083 /*----------------------------*/
3084 /* straight assignemnt */
3085 /*----------------------------*/
3087 /* cannot be an aggregate */
3088 if (IS_AGGREGATE (LTYPE (tree)))
3090 werror (E_AGGR_ASSIGN);
3091 goto errorTreeReturn;
3094 /* they should either match or be castable */
3095 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3097 werror (E_TYPE_MISMATCH, "assignment", " ");
3098 fprintf (stderr, "type --> '");
3099 printTypeChain (RTYPE (tree), stderr);
3100 fprintf (stderr, "' ");
3101 fprintf (stderr, "assigned to type --> '");
3102 printTypeChain (LTYPE (tree), stderr);
3103 fprintf (stderr, "'\n");
3104 goto errorTreeReturn;
3107 /* if the left side of the tree is of type void
3108 then report error */
3109 if (IS_VOID (LTYPE (tree)))
3111 werror (E_CAST_ZERO);
3112 printFromToType(RTYPE(tree), LTYPE(tree));
3115 TETYPE (tree) = getSpec (TTYPE (tree) =
3119 if (!tree->initMode ) {
3120 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3121 werror (E_CODE_WRITE, " ");
3125 werror (E_LVALUE_REQUIRED, "=");
3126 goto errorTreeReturn;
3131 /*------------------------------------------------------------------*/
3132 /*----------------------------*/
3133 /* comma operator */
3134 /*----------------------------*/
3136 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3139 /*------------------------------------------------------------------*/
3140 /*----------------------------*/
3142 /*----------------------------*/
3146 if (processParms (tree->left,
3147 FUNC_ARGS(tree->left->ftype),
3148 tree->right, &parmNumber, TRUE)) {
3149 goto errorTreeReturn;
3152 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3153 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3155 //FUNC_ARGS(tree->left->ftype) =
3156 //reverseVal (FUNC_ARGS(tree->left->ftype));
3157 reverseParms (tree->right);
3160 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3163 /*------------------------------------------------------------------*/
3164 /*----------------------------*/
3165 /* return statement */
3166 /*----------------------------*/
3171 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3173 werror (W_RETURN_MISMATCH);
3174 printFromToType (RTYPE(tree), currFunc->type->next);
3175 goto errorTreeReturn;
3178 if (IS_VOID (currFunc->type->next)
3180 !IS_VOID (RTYPE (tree)))
3182 werror (E_FUNC_VOID);
3183 goto errorTreeReturn;
3186 /* if there is going to be a casing required then add it */
3187 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3190 decorateType (newNode (CAST,
3191 newAst_LINK (copyLinkChain (currFunc->type->next)),
3200 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3202 werror (E_VOID_FUNC, currFunc->name);
3203 goto errorTreeReturn;
3206 TTYPE (tree) = TETYPE (tree) = NULL;
3209 /*------------------------------------------------------------------*/
3210 /*----------------------------*/
3211 /* switch statement */
3212 /*----------------------------*/
3214 /* the switch value must be an integer */
3215 if (!IS_INTEGRAL (LTYPE (tree)))
3217 werror (E_SWITCH_NON_INTEGER);
3218 goto errorTreeReturn;
3221 TTYPE (tree) = TETYPE (tree) = NULL;
3224 /*------------------------------------------------------------------*/
3225 /*----------------------------*/
3227 /*----------------------------*/
3229 tree->left = backPatchLabels (tree->left,
3232 TTYPE (tree) = TETYPE (tree) = NULL;
3235 /*------------------------------------------------------------------*/
3236 /*----------------------------*/
3238 /*----------------------------*/
3241 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3242 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3243 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3245 /* if the for loop is reversible then
3246 reverse it otherwise do what we normally
3252 if (isLoopReversible (tree, &sym, &init, &end))
3253 return reverseLoop (tree, sym, init, end);
3255 return decorateType (createFor (AST_FOR (tree, trueLabel),
3256 AST_FOR (tree, continueLabel),
3257 AST_FOR (tree, falseLabel),
3258 AST_FOR (tree, condLabel),
3259 AST_FOR (tree, initExpr),
3260 AST_FOR (tree, condExpr),
3261 AST_FOR (tree, loopExpr),
3265 TTYPE (tree) = TETYPE (tree) = NULL;
3269 /* some error found this tree will be killed */
3271 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3272 tree->opval.op = NULLOP;
3278 /*-----------------------------------------------------------------*/
3279 /* sizeofOp - processes size of operation */
3280 /*-----------------------------------------------------------------*/
3282 sizeofOp (sym_link * type)
3286 /* make sure the type is complete and sane */
3287 checkTypeSanity(type, "(sizeof)");
3289 /* get the size and convert it to character */
3290 sprintf (buff, "%d", getSize (type));
3292 /* now convert into value */
3293 return constVal (buff);
3297 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3298 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3299 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3300 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3301 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3302 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3303 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3305 /*-----------------------------------------------------------------*/
3306 /* backPatchLabels - change and or not operators to flow control */
3307 /*-----------------------------------------------------------------*/
3309 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3315 if (!(IS_ANDORNOT (tree)))
3318 /* if this an and */
3321 static int localLbl = 0;
3324 sprintf (buffer, "_and_%d", localLbl++);
3325 localLabel = newSymbol (buffer, NestLevel);
3327 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3329 /* if left is already a IFX then just change the if true label in that */
3330 if (!IS_IFX (tree->left))
3331 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3333 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3334 /* right is a IFX then just join */
3335 if (IS_IFX (tree->right))
3336 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3338 tree->right = createLabel (localLabel, tree->right);
3339 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3341 return newNode (NULLOP, tree->left, tree->right);
3344 /* if this is an or operation */
3347 static int localLbl = 0;
3350 sprintf (buffer, "_or_%d", localLbl++);
3351 localLabel = newSymbol (buffer, NestLevel);
3353 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3355 /* if left is already a IFX then just change the if true label in that */
3356 if (!IS_IFX (tree->left))
3357 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3359 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3360 /* right is a IFX then just join */
3361 if (IS_IFX (tree->right))
3362 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3364 tree->right = createLabel (localLabel, tree->right);
3365 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3367 return newNode (NULLOP, tree->left, tree->right);
3373 int wasnot = IS_NOT (tree->left);
3374 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3376 /* if the left is already a IFX */
3377 if (!IS_IFX (tree->left))
3378 tree->left = newNode (IFX, tree->left, NULL);
3382 tree->left->trueLabel = trueLabel;
3383 tree->left->falseLabel = falseLabel;
3387 tree->left->trueLabel = falseLabel;
3388 tree->left->falseLabel = trueLabel;
3395 tree->trueLabel = trueLabel;
3396 tree->falseLabel = falseLabel;
3403 /*-----------------------------------------------------------------*/
3404 /* createBlock - create expression tree for block */
3405 /*-----------------------------------------------------------------*/
3407 createBlock (symbol * decl, ast * body)
3411 /* if the block has nothing */
3415 ex = newNode (BLOCK, NULL, body);
3416 ex->values.sym = decl;
3418 ex->right = ex->right;
3424 /*-----------------------------------------------------------------*/
3425 /* createLabel - creates the expression tree for labels */
3426 /*-----------------------------------------------------------------*/
3428 createLabel (symbol * label, ast * stmnt)
3431 char name[SDCC_NAME_MAX + 1];
3434 /* must create fresh symbol if the symbol name */
3435 /* exists in the symbol table, since there can */
3436 /* be a variable with the same name as the labl */
3437 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3438 (csym->level == label->level))
3439 label = newSymbol (label->name, label->level);
3441 /* change the name before putting it in add _ */
3442 sprintf (name, "%s", label->name);
3444 /* put the label in the LabelSymbol table */
3445 /* but first check if a label of the same */
3447 if ((csym = findSym (LabelTab, NULL, name)))
3448 werror (E_DUPLICATE_LABEL, label->name);
3450 addSym (LabelTab, label, name, label->level, 0, 0);
3453 label->key = labelKey++;
3454 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3460 /*-----------------------------------------------------------------*/
3461 /* createCase - generates the parsetree for a case statement */
3462 /*-----------------------------------------------------------------*/
3464 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3466 char caseLbl[SDCC_NAME_MAX + 1];
3470 /* if the switch statement does not exist */
3471 /* then case is out of context */
3474 werror (E_CASE_CONTEXT);
3478 caseVal = decorateType (resolveSymbols (caseVal));
3479 /* if not a constant then error */
3480 if (!IS_LITERAL (caseVal->ftype))
3482 werror (E_CASE_CONSTANT);
3486 /* if not a integer than error */
3487 if (!IS_INTEGRAL (caseVal->ftype))
3489 werror (E_CASE_NON_INTEGER);
3493 /* find the end of the switch values chain */
3494 if (!(val = swStat->values.switchVals.swVals))
3495 swStat->values.switchVals.swVals = caseVal->opval.val;
3498 /* also order the cases according to value */
3500 int cVal = (int) floatFromVal (caseVal->opval.val);
3501 while (val && (int) floatFromVal (val) < cVal)
3507 /* if we reached the end then */
3510 pval->next = caseVal->opval.val;
3514 /* we found a value greater than */
3515 /* the current value we must add this */
3516 /* before the value */
3517 caseVal->opval.val->next = val;
3519 /* if this was the first in chain */
3520 if (swStat->values.switchVals.swVals == val)
3521 swStat->values.switchVals.swVals =
3524 pval->next = caseVal->opval.val;
3529 /* create the case label */
3530 sprintf (caseLbl, "_case_%d_%d",
3531 swStat->values.switchVals.swNum,
3532 (int) floatFromVal (caseVal->opval.val));
3534 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3539 /*-----------------------------------------------------------------*/
3540 /* createDefault - creates the parse tree for the default statement */
3541 /*-----------------------------------------------------------------*/
3543 createDefault (ast * swStat, ast * stmnt)
3545 char defLbl[SDCC_NAME_MAX + 1];
3547 /* if the switch statement does not exist */
3548 /* then case is out of context */
3551 werror (E_CASE_CONTEXT);
3555 /* turn on the default flag */
3556 swStat->values.switchVals.swDefault = 1;
3558 /* create the label */
3559 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3560 return createLabel (newSymbol (defLbl, 0), stmnt);
3563 /*-----------------------------------------------------------------*/
3564 /* createIf - creates the parsetree for the if statement */
3565 /*-----------------------------------------------------------------*/
3567 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3569 static int Lblnum = 0;
3571 symbol *ifTrue, *ifFalse, *ifEnd;
3573 /* if neither exists */
3574 if (!elseBody && !ifBody) {
3575 // if there are no side effects (i++, j() etc)
3576 if (!hasSEFcalls(condAst)) {
3581 /* create the labels */
3582 sprintf (buffer, "_iffalse_%d", Lblnum);
3583 ifFalse = newSymbol (buffer, NestLevel);
3584 /* if no else body then end == false */
3589 sprintf (buffer, "_ifend_%d", Lblnum);
3590 ifEnd = newSymbol (buffer, NestLevel);
3593 sprintf (buffer, "_iftrue_%d", Lblnum);
3594 ifTrue = newSymbol (buffer, NestLevel);
3598 /* attach the ifTrue label to the top of it body */
3599 ifBody = createLabel (ifTrue, ifBody);
3600 /* attach a goto end to the ifBody if else is present */
3603 ifBody = newNode (NULLOP, ifBody,
3605 newAst_VALUE (symbolVal (ifEnd)),
3607 /* put the elseLabel on the else body */
3608 elseBody = createLabel (ifFalse, elseBody);
3609 /* out the end at the end of the body */
3610 elseBody = newNode (NULLOP,
3612 createLabel (ifEnd, NULL));
3616 ifBody = newNode (NULLOP, ifBody,
3617 createLabel (ifFalse, NULL));
3619 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3620 if (IS_IFX (condAst))
3623 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3625 return newNode (NULLOP, ifTree,
3626 newNode (NULLOP, ifBody, elseBody));
3630 /*-----------------------------------------------------------------*/
3631 /* createDo - creates parse tree for do */
3634 /* _docontinue_n: */
3635 /* condition_expression +-> trueLabel -> _dobody_n */
3637 /* +-> falseLabel-> _dobreak_n */
3639 /*-----------------------------------------------------------------*/
3641 createDo (symbol * trueLabel, symbol * continueLabel,
3642 symbol * falseLabel, ast * condAst, ast * doBody)
3647 /* if the body does not exist then it is simple */
3650 condAst = backPatchLabels (condAst, continueLabel, NULL);
3651 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3652 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3653 doTree->trueLabel = continueLabel;
3654 doTree->falseLabel = NULL;
3658 /* otherwise we have a body */
3659 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3661 /* attach the body label to the top */
3662 doBody = createLabel (trueLabel, doBody);
3663 /* attach the continue label to end of body */
3664 doBody = newNode (NULLOP, doBody,
3665 createLabel (continueLabel, NULL));
3667 /* now put the break label at the end */
3668 if (IS_IFX (condAst))
3671 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3673 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3675 /* putting it together */
3676 return newNode (NULLOP, doBody, doTree);
3679 /*-----------------------------------------------------------------*/
3680 /* createFor - creates parse tree for 'for' statement */
3683 /* condExpr +-> trueLabel -> _forbody_n */
3685 /* +-> falseLabel-> _forbreak_n */
3688 /* _forcontinue_n: */
3690 /* goto _forcond_n ; */
3692 /*-----------------------------------------------------------------*/
3694 createFor (symbol * trueLabel, symbol * continueLabel,
3695 symbol * falseLabel, symbol * condLabel,
3696 ast * initExpr, ast * condExpr, ast * loopExpr,
3701 /* if loopexpression not present then we can generate it */
3702 /* the same way as a while */
3704 return newNode (NULLOP, initExpr,
3705 createWhile (trueLabel, continueLabel,
3706 falseLabel, condExpr, forBody));
3707 /* vanilla for statement */
3708 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3710 if (condExpr && !IS_IFX (condExpr))
3711 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3714 /* attach condition label to condition */
3715 condExpr = createLabel (condLabel, condExpr);
3717 /* attach body label to body */
3718 forBody = createLabel (trueLabel, forBody);
3720 /* attach continue to forLoop expression & attach */
3721 /* goto the forcond @ and of loopExpression */
3722 loopExpr = createLabel (continueLabel,
3726 newAst_VALUE (symbolVal (condLabel)),
3728 /* now start putting them together */
3729 forTree = newNode (NULLOP, initExpr, condExpr);
3730 forTree = newNode (NULLOP, forTree, forBody);
3731 forTree = newNode (NULLOP, forTree, loopExpr);
3732 /* finally add the break label */
3733 forTree = newNode (NULLOP, forTree,
3734 createLabel (falseLabel, NULL));
3738 /*-----------------------------------------------------------------*/
3739 /* createWhile - creates parse tree for while statement */
3740 /* the while statement will be created as follows */
3742 /* _while_continue_n: */
3743 /* condition_expression +-> trueLabel -> _while_boby_n */
3745 /* +-> falseLabel -> _while_break_n */
3746 /* _while_body_n: */
3748 /* goto _while_continue_n */
3749 /* _while_break_n: */
3750 /*-----------------------------------------------------------------*/
3752 createWhile (symbol * trueLabel, symbol * continueLabel,
3753 symbol * falseLabel, ast * condExpr, ast * whileBody)
3757 /* put the continue label */
3758 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3759 condExpr = createLabel (continueLabel, condExpr);
3760 condExpr->lineno = 0;
3762 /* put the body label in front of the body */
3763 whileBody = createLabel (trueLabel, whileBody);
3764 whileBody->lineno = 0;
3765 /* put a jump to continue at the end of the body */
3766 /* and put break label at the end of the body */
3767 whileBody = newNode (NULLOP,
3770 newAst_VALUE (symbolVal (continueLabel)),
3771 createLabel (falseLabel, NULL)));
3773 /* put it all together */
3774 if (IS_IFX (condExpr))
3775 whileTree = condExpr;
3778 whileTree = newNode (IFX, condExpr, NULL);
3779 /* put the true & false labels in place */
3780 whileTree->trueLabel = trueLabel;
3781 whileTree->falseLabel = falseLabel;
3784 return newNode (NULLOP, whileTree, whileBody);
3787 /*-----------------------------------------------------------------*/
3788 /* optimizeGetHbit - get highest order bit of the expression */
3789 /*-----------------------------------------------------------------*/
3791 optimizeGetHbit (ast * tree)
3794 /* if this is not a bit and */
3795 if (!IS_BITAND (tree))
3798 /* will look for tree of the form
3799 ( expr >> ((sizeof expr) -1) ) & 1 */
3800 if (!IS_AST_LIT_VALUE (tree->right))
3803 if (AST_LIT_VALUE (tree->right) != 1)
3806 if (!IS_RIGHT_OP (tree->left))
3809 if (!IS_AST_LIT_VALUE (tree->left->right))
3812 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3813 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3816 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3820 /*-----------------------------------------------------------------*/
3821 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3822 /*-----------------------------------------------------------------*/
3824 optimizeRRCRLC (ast * root)
3826 /* will look for trees of the form
3827 (?expr << 1) | (?expr >> 7) or
3828 (?expr >> 7) | (?expr << 1) will make that
3829 into a RLC : operation ..
3831 (?expr >> 1) | (?expr << 7) or
3832 (?expr << 7) | (?expr >> 1) will make that
3833 into a RRC operation
3834 note : by 7 I mean (number of bits required to hold the
3836 /* if the root operations is not a | operation the not */
3837 if (!IS_BITOR (root))
3840 /* I have to think of a better way to match patterns this sucks */
3841 /* that aside let start looking for the first case : I use a the
3842 negative check a lot to improve the efficiency */
3843 /* (?expr << 1) | (?expr >> 7) */
3844 if (IS_LEFT_OP (root->left) &&
3845 IS_RIGHT_OP (root->right))
3848 if (!SPEC_USIGN (TETYPE (root->left->left)))
3851 if (!IS_AST_LIT_VALUE (root->left->right) ||
3852 !IS_AST_LIT_VALUE (root->right->right))
3855 /* make sure it is the same expression */
3856 if (!isAstEqual (root->left->left,
3860 if (AST_LIT_VALUE (root->left->right) != 1)
3863 if (AST_LIT_VALUE (root->right->right) !=
3864 (getSize (TTYPE (root->left->left)) * 8 - 1))
3867 /* whew got the first case : create the AST */
3868 return newNode (RLC, root->left->left, NULL);
3872 /* check for second case */
3873 /* (?expr >> 7) | (?expr << 1) */
3874 if (IS_LEFT_OP (root->right) &&
3875 IS_RIGHT_OP (root->left))
3878 if (!SPEC_USIGN (TETYPE (root->left->left)))
3881 if (!IS_AST_LIT_VALUE (root->left->right) ||
3882 !IS_AST_LIT_VALUE (root->right->right))
3885 /* make sure it is the same symbol */
3886 if (!isAstEqual (root->left->left,
3890 if (AST_LIT_VALUE (root->right->right) != 1)
3893 if (AST_LIT_VALUE (root->left->right) !=
3894 (getSize (TTYPE (root->left->left)) * 8 - 1))
3897 /* whew got the first case : create the AST */
3898 return newNode (RLC, root->left->left, NULL);
3903 /* third case for RRC */
3904 /* (?symbol >> 1) | (?symbol << 7) */
3905 if (IS_LEFT_OP (root->right) &&
3906 IS_RIGHT_OP (root->left))
3909 if (!SPEC_USIGN (TETYPE (root->left->left)))
3912 if (!IS_AST_LIT_VALUE (root->left->right) ||
3913 !IS_AST_LIT_VALUE (root->right->right))
3916 /* make sure it is the same symbol */
3917 if (!isAstEqual (root->left->left,
3921 if (AST_LIT_VALUE (root->left->right) != 1)
3924 if (AST_LIT_VALUE (root->right->right) !=
3925 (getSize (TTYPE (root->left->left)) * 8 - 1))
3928 /* whew got the first case : create the AST */
3929 return newNode (RRC, root->left->left, NULL);
3933 /* fourth and last case for now */
3934 /* (?symbol << 7) | (?symbol >> 1) */
3935 if (IS_RIGHT_OP (root->right) &&
3936 IS_LEFT_OP (root->left))
3939 if (!SPEC_USIGN (TETYPE (root->left->left)))
3942 if (!IS_AST_LIT_VALUE (root->left->right) ||
3943 !IS_AST_LIT_VALUE (root->right->right))
3946 /* make sure it is the same symbol */
3947 if (!isAstEqual (root->left->left,
3951 if (AST_LIT_VALUE (root->right->right) != 1)
3954 if (AST_LIT_VALUE (root->left->right) !=
3955 (getSize (TTYPE (root->left->left)) * 8 - 1))
3958 /* whew got the first case : create the AST */
3959 return newNode (RRC, root->left->left, NULL);
3963 /* not found return root */
3967 /*-----------------------------------------------------------------*/
3968 /* optimizeCompare - otimizes compares for bit variables */
3969 /*-----------------------------------------------------------------*/
3971 optimizeCompare (ast * root)
3973 ast *optExpr = NULL;
3976 unsigned int litValue;
3978 /* if nothing then return nothing */
3982 /* if not a compare op then do leaves */
3983 if (!IS_COMPARE_OP (root))
3985 root->left = optimizeCompare (root->left);
3986 root->right = optimizeCompare (root->right);
3990 /* if left & right are the same then depending
3991 of the operation do */
3992 if (isAstEqual (root->left, root->right))
3994 switch (root->opval.op)
3999 optExpr = newAst_VALUE (constVal ("0"));
4004 optExpr = newAst_VALUE (constVal ("1"));
4008 return decorateType (optExpr);
4011 vleft = (root->left->type == EX_VALUE ?
4012 root->left->opval.val : NULL);
4014 vright = (root->right->type == EX_VALUE ?
4015 root->right->opval.val : NULL);
4017 /* if left is a BITVAR in BITSPACE */
4018 /* and right is a LITERAL then opt- */
4019 /* imize else do nothing */
4020 if (vleft && vright &&
4021 IS_BITVAR (vleft->etype) &&
4022 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4023 IS_LITERAL (vright->etype))
4026 /* if right side > 1 then comparison may never succeed */
4027 if ((litValue = (int) floatFromVal (vright)) > 1)
4029 werror (W_BAD_COMPARE);
4035 switch (root->opval.op)
4037 case '>': /* bit value greater than 1 cannot be */
4038 werror (W_BAD_COMPARE);
4042 case '<': /* bit value < 1 means 0 */
4044 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4047 case LE_OP: /* bit value <= 1 means no check */
4048 optExpr = newAst_VALUE (vright);
4051 case GE_OP: /* bit value >= 1 means only check for = */
4053 optExpr = newAst_VALUE (vleft);
4058 { /* literal is zero */
4059 switch (root->opval.op)
4061 case '<': /* bit value < 0 cannot be */
4062 werror (W_BAD_COMPARE);
4066 case '>': /* bit value > 0 means 1 */
4068 optExpr = newAst_VALUE (vleft);
4071 case LE_OP: /* bit value <= 0 means no check */
4072 case GE_OP: /* bit value >= 0 means no check */
4073 werror (W_BAD_COMPARE);
4077 case EQ_OP: /* bit == 0 means ! of bit */
4078 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4082 return decorateType (resolveSymbols (optExpr));
4083 } /* end-of-if of BITVAR */
4088 /*-----------------------------------------------------------------*/
4089 /* addSymToBlock : adds the symbol to the first block we find */
4090 /*-----------------------------------------------------------------*/
4092 addSymToBlock (symbol * sym, ast * tree)
4094 /* reached end of tree or a leaf */
4095 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4099 if (IS_AST_OP (tree) &&
4100 tree->opval.op == BLOCK)
4103 symbol *lsym = copySymbol (sym);
4105 lsym->next = AST_VALUES (tree, sym);
4106 AST_VALUES (tree, sym) = lsym;
4110 addSymToBlock (sym, tree->left);
4111 addSymToBlock (sym, tree->right);
4114 /*-----------------------------------------------------------------*/
4115 /* processRegParms - do processing for register parameters */
4116 /*-----------------------------------------------------------------*/
4118 processRegParms (value * args, ast * body)
4122 if (IS_REGPARM (args->etype))
4123 addSymToBlock (args->sym, body);
4128 /*-----------------------------------------------------------------*/
4129 /* resetParmKey - resets the operandkeys for the symbols */
4130 /*-----------------------------------------------------------------*/
4131 DEFSETFUNC (resetParmKey)
4142 /*-----------------------------------------------------------------*/
4143 /* createFunction - This is the key node that calls the iCode for */
4144 /* generating the code for a function. Note code */
4145 /* is generated function by function, later when */
4146 /* add inter-procedural analysis this will change */
4147 /*-----------------------------------------------------------------*/
4149 createFunction (symbol * name, ast * body)
4155 iCode *piCode = NULL;
4157 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4158 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4160 /* if check function return 0 then some problem */
4161 if (checkFunction (name, NULL) == 0)
4164 /* create a dummy block if none exists */
4166 body = newNode (BLOCK, NULL, NULL);
4170 /* check if the function name already in the symbol table */
4171 if ((csym = findSym (SymbolTab, NULL, name->name)))
4174 /* special case for compiler defined functions
4175 we need to add the name to the publics list : this
4176 actually means we are now compiling the compiler
4180 addSet (&publics, name);
4186 allocVariables (name);
4188 name->lastLine = yylineno;
4191 /* set the stack pointer */
4192 /* PENDING: check this for the mcs51 */
4193 stackPtr = -port->stack.direction * port->stack.call_overhead;
4194 if (IFFUNC_ISISR (name->type))
4195 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4196 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4197 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4199 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4201 fetype = getSpec (name->type); /* get the specifier for the function */
4202 /* if this is a reentrant function then */
4203 if (IFFUNC_ISREENT (name->type))
4206 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4208 /* do processing for parameters that are passed in registers */
4209 processRegParms (FUNC_ARGS(name->type), body);
4211 /* set the stack pointer */
4215 /* allocate & autoinit the block variables */
4216 processBlockVars (body, &stack, ALLOCATE);
4218 /* save the stack information */
4219 if (options.useXstack)
4220 name->xstack = SPEC_STAK (fetype) = stack;
4222 name->stack = SPEC_STAK (fetype) = stack;
4224 /* name needs to be mangled */
4225 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4227 body = resolveSymbols (body); /* resolve the symbols */
4228 body = decorateType (body); /* propagateType & do semantic checks */
4230 ex = newAst_VALUE (symbolVal (name)); /* create name */
4231 ex = newNode (FUNCTION, ex, body);
4232 ex->values.args = FUNC_ARGS(name->type);
4234 if (options.dump_tree) PA(ex);
4237 werror (E_FUNC_NO_CODE, name->name);
4241 /* create the node & generate intermediate code */
4243 codeOutFile = code->oFile;
4244 piCode = iCodeFromAst (ex);
4248 werror (E_FUNC_NO_CODE, name->name);
4252 eBBlockFromiCode (piCode);
4254 /* if there are any statics then do them */
4257 GcurMemmap = statsg;
4258 codeOutFile = statsg->oFile;
4259 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4265 /* dealloc the block variables */
4266 processBlockVars (body, &stack, DEALLOCATE);
4267 /* deallocate paramaters */
4268 deallocParms (FUNC_ARGS(name->type));
4270 if (IFFUNC_ISREENT (name->type))
4273 /* we are done freeup memory & cleanup */
4275 if (port->reset_labelKey) labelKey = 1;
4277 FUNC_HASBODY(name->type) = 1;
4278 addSet (&operKeyReset, name);
4279 applyToSet (operKeyReset, resetParmKey);
4282 cdbStructBlock (1, cdbFile);
4284 cleanUpLevel (LabelTab, 0);
4285 cleanUpBlock (StructTab, 1);
4286 cleanUpBlock (TypedefTab, 1);
4288 xstack->syms = NULL;
4289 istack->syms = NULL;
4294 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4295 /*-----------------------------------------------------------------*/
4296 /* ast_print : prints the ast (for debugging purposes) */
4297 /*-----------------------------------------------------------------*/
4299 void ast_print (ast * tree, FILE *outfile, int indent)
4304 /* can print only decorated trees */
4305 if (!tree->decorated) return;
4307 /* if any child is an error | this one is an error do nothing */
4308 if (tree->isError ||
4309 (tree->left && tree->left->isError) ||
4310 (tree->right && tree->right->isError)) {
4311 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4315 /* print the line */
4316 /* if not block & function */
4317 if (tree->type == EX_OP &&
4318 (tree->opval.op != FUNCTION &&
4319 tree->opval.op != BLOCK &&
4320 tree->opval.op != NULLOP)) {
4323 if (tree->opval.op == FUNCTION) {
4325 value *args=FUNC_ARGS(tree->left->opval.val->type);
4326 fprintf(outfile,"FUNCTION (%s=%p) type (",
4327 tree->left->opval.val->name, tree);
4328 printTypeChain (tree->ftype,outfile);
4329 fprintf(outfile,") args (");
4332 fprintf (outfile, ", ");
4334 printTypeChain (args ? args->type : NULL, outfile);
4336 args= args ? args->next : NULL;
4338 fprintf(outfile,")\n");
4339 ast_print(tree->left,outfile,indent);
4340 ast_print(tree->right,outfile,indent);
4343 if (tree->opval.op == BLOCK) {
4344 symbol *decls = tree->values.sym;
4345 INDENT(indent,outfile);
4346 fprintf(outfile,"{\n");
4348 INDENT(indent+2,outfile);
4349 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4350 decls->name, decls);
4351 printTypeChain(decls->type,outfile);
4352 fprintf(outfile,")\n");
4354 decls = decls->next;
4356 ast_print(tree->right,outfile,indent+2);
4357 INDENT(indent,outfile);
4358 fprintf(outfile,"}\n");
4361 if (tree->opval.op == NULLOP) {
4362 fprintf(outfile,"\n");
4363 ast_print(tree->left,outfile,indent);
4364 fprintf(outfile,"\n");
4365 ast_print(tree->right,outfile,indent);
4368 INDENT(indent,outfile);
4370 /*------------------------------------------------------------------*/
4371 /*----------------------------*/
4372 /* leaf has been reached */
4373 /*----------------------------*/
4374 /* if this is of type value */
4375 /* just get the type */
4376 if (tree->type == EX_VALUE) {
4378 if (IS_LITERAL (tree->opval.val->etype)) {
4379 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4380 (int) floatFromVal(tree->opval.val),
4381 (int) floatFromVal(tree->opval.val),
4382 floatFromVal(tree->opval.val));
4383 } else if (tree->opval.val->sym) {
4384 /* if the undefined flag is set then give error message */
4385 if (tree->opval.val->sym->undefined) {
4386 fprintf(outfile,"UNDEFINED SYMBOL ");
4388 fprintf(outfile,"SYMBOL ");
4390 fprintf(outfile,"(%s=%p)",
4391 tree->opval.val->sym->name,tree);
4394 fprintf(outfile," type (");
4395 printTypeChain(tree->ftype,outfile);
4396 fprintf(outfile,")\n");
4398 fprintf(outfile,"\n");
4403 /* if type link for the case of cast */
4404 if (tree->type == EX_LINK) {
4405 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4406 printTypeChain(tree->opval.lnk,outfile);
4407 fprintf(outfile,")\n");
4412 /* depending on type of operator do */
4414 switch (tree->opval.op) {
4415 /*------------------------------------------------------------------*/
4416 /*----------------------------*/
4418 /*----------------------------*/
4420 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4421 printTypeChain(tree->ftype,outfile);
4422 fprintf(outfile,")\n");
4423 ast_print(tree->left,outfile,indent+2);
4424 ast_print(tree->right,outfile,indent+2);
4427 /*------------------------------------------------------------------*/
4428 /*----------------------------*/
4430 /*----------------------------*/
4432 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4433 printTypeChain(tree->ftype,outfile);
4434 fprintf(outfile,")\n");
4435 ast_print(tree->left,outfile,indent+2);
4436 ast_print(tree->right,outfile,indent+2);
4439 /*------------------------------------------------------------------*/
4440 /*----------------------------*/
4441 /* struct/union pointer */
4442 /*----------------------------*/
4444 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4445 printTypeChain(tree->ftype,outfile);
4446 fprintf(outfile,")\n");
4447 ast_print(tree->left,outfile,indent+2);
4448 ast_print(tree->right,outfile,indent+2);
4451 /*------------------------------------------------------------------*/
4452 /*----------------------------*/
4453 /* ++/-- operation */
4454 /*----------------------------*/
4455 case INC_OP: /* incerement operator unary so left only */
4456 fprintf(outfile,"INC_OP (%p) type (",tree);
4457 printTypeChain(tree->ftype,outfile);
4458 fprintf(outfile,")\n");
4459 ast_print(tree->left,outfile,indent+2);
4463 fprintf(outfile,"DEC_OP (%p) type (",tree);
4464 printTypeChain(tree->ftype,outfile);
4465 fprintf(outfile,")\n");
4466 ast_print(tree->left,outfile,indent+2);
4469 /*------------------------------------------------------------------*/
4470 /*----------------------------*/
4472 /*----------------------------*/
4475 fprintf(outfile,"& (%p) type (",tree);
4476 printTypeChain(tree->ftype,outfile);
4477 fprintf(outfile,")\n");
4478 ast_print(tree->left,outfile,indent+2);
4479 ast_print(tree->right,outfile,indent+2);
4481 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4482 printTypeChain(tree->ftype,outfile);
4483 fprintf(outfile,")\n");
4484 ast_print(tree->left,outfile,indent+2);
4485 ast_print(tree->right,outfile,indent+2);
4488 /*----------------------------*/
4490 /*----------------------------*/
4492 fprintf(outfile,"OR (%p) type (",tree);
4493 printTypeChain(tree->ftype,outfile);
4494 fprintf(outfile,")\n");
4495 ast_print(tree->left,outfile,indent+2);
4496 ast_print(tree->right,outfile,indent+2);
4498 /*------------------------------------------------------------------*/
4499 /*----------------------------*/
4501 /*----------------------------*/
4503 fprintf(outfile,"XOR (%p) type (",tree);
4504 printTypeChain(tree->ftype,outfile);
4505 fprintf(outfile,")\n");
4506 ast_print(tree->left,outfile,indent+2);
4507 ast_print(tree->right,outfile,indent+2);
4510 /*------------------------------------------------------------------*/
4511 /*----------------------------*/
4513 /*----------------------------*/
4515 fprintf(outfile,"DIV (%p) type (",tree);
4516 printTypeChain(tree->ftype,outfile);
4517 fprintf(outfile,")\n");
4518 ast_print(tree->left,outfile,indent+2);
4519 ast_print(tree->right,outfile,indent+2);
4521 /*------------------------------------------------------------------*/
4522 /*----------------------------*/
4524 /*----------------------------*/
4526 fprintf(outfile,"MOD (%p) type (",tree);
4527 printTypeChain(tree->ftype,outfile);
4528 fprintf(outfile,")\n");
4529 ast_print(tree->left,outfile,indent+2);
4530 ast_print(tree->right,outfile,indent+2);
4533 /*------------------------------------------------------------------*/
4534 /*----------------------------*/
4535 /* address dereference */
4536 /*----------------------------*/
4537 case '*': /* can be unary : if right is null then unary operation */
4539 fprintf(outfile,"DEREF (%p) type (",tree);
4540 printTypeChain(tree->ftype,outfile);
4541 fprintf(outfile,")\n");
4542 ast_print(tree->left,outfile,indent+2);
4545 /*------------------------------------------------------------------*/
4546 /*----------------------------*/
4547 /* multiplication */
4548 /*----------------------------*/
4549 fprintf(outfile,"MULT (%p) type (",tree);
4550 printTypeChain(tree->ftype,outfile);
4551 fprintf(outfile,")\n");
4552 ast_print(tree->left,outfile,indent+2);
4553 ast_print(tree->right,outfile,indent+2);
4557 /*------------------------------------------------------------------*/
4558 /*----------------------------*/
4559 /* unary '+' operator */
4560 /*----------------------------*/
4564 fprintf(outfile,"UPLUS (%p) type (",tree);
4565 printTypeChain(tree->ftype,outfile);
4566 fprintf(outfile,")\n");
4567 ast_print(tree->left,outfile,indent+2);
4569 /*------------------------------------------------------------------*/
4570 /*----------------------------*/
4572 /*----------------------------*/
4573 fprintf(outfile,"ADD (%p) type (",tree);
4574 printTypeChain(tree->ftype,outfile);
4575 fprintf(outfile,")\n");
4576 ast_print(tree->left,outfile,indent+2);
4577 ast_print(tree->right,outfile,indent+2);
4580 /*------------------------------------------------------------------*/
4581 /*----------------------------*/
4583 /*----------------------------*/
4584 case '-': /* can be unary */
4586 fprintf(outfile,"UMINUS (%p) type (",tree);
4587 printTypeChain(tree->ftype,outfile);
4588 fprintf(outfile,")\n");
4589 ast_print(tree->left,outfile,indent+2);
4591 /*------------------------------------------------------------------*/
4592 /*----------------------------*/
4594 /*----------------------------*/
4595 fprintf(outfile,"SUB (%p) type (",tree);
4596 printTypeChain(tree->ftype,outfile);
4597 fprintf(outfile,")\n");
4598 ast_print(tree->left,outfile,indent+2);
4599 ast_print(tree->right,outfile,indent+2);
4602 /*------------------------------------------------------------------*/
4603 /*----------------------------*/
4605 /*----------------------------*/
4607 fprintf(outfile,"COMPL (%p) type (",tree);
4608 printTypeChain(tree->ftype,outfile);
4609 fprintf(outfile,")\n");
4610 ast_print(tree->left,outfile,indent+2);
4612 /*------------------------------------------------------------------*/
4613 /*----------------------------*/
4615 /*----------------------------*/
4617 fprintf(outfile,"NOT (%p) type (",tree);
4618 printTypeChain(tree->ftype,outfile);
4619 fprintf(outfile,")\n");
4620 ast_print(tree->left,outfile,indent+2);
4622 /*------------------------------------------------------------------*/
4623 /*----------------------------*/
4625 /*----------------------------*/
4627 fprintf(outfile,"RRC (%p) type (",tree);
4628 printTypeChain(tree->ftype,outfile);
4629 fprintf(outfile,")\n");
4630 ast_print(tree->left,outfile,indent+2);
4634 fprintf(outfile,"RLC (%p) type (",tree);
4635 printTypeChain(tree->ftype,outfile);
4636 fprintf(outfile,")\n");
4637 ast_print(tree->left,outfile,indent+2);
4640 fprintf(outfile,"GETHBIT (%p) type (",tree);
4641 printTypeChain(tree->ftype,outfile);
4642 fprintf(outfile,")\n");
4643 ast_print(tree->left,outfile,indent+2);
4646 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4647 printTypeChain(tree->ftype,outfile);
4648 fprintf(outfile,")\n");
4649 ast_print(tree->left,outfile,indent+2);
4650 ast_print(tree->right,outfile,indent+2);
4653 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4654 printTypeChain(tree->ftype,outfile);
4655 fprintf(outfile,")\n");
4656 ast_print(tree->left,outfile,indent+2);
4657 ast_print(tree->right,outfile,indent+2);
4659 /*------------------------------------------------------------------*/
4660 /*----------------------------*/
4662 /*----------------------------*/
4663 case CAST: /* change the type */
4664 fprintf(outfile,"CAST (%p) from type (",tree);
4665 printTypeChain(tree->right->ftype,outfile);
4666 fprintf(outfile,") to type (");
4667 printTypeChain(tree->ftype,outfile);
4668 fprintf(outfile,")\n");
4669 ast_print(tree->right,outfile,indent+2);
4673 fprintf(outfile,"ANDAND (%p) type (",tree);
4674 printTypeChain(tree->ftype,outfile);
4675 fprintf(outfile,")\n");
4676 ast_print(tree->left,outfile,indent+2);
4677 ast_print(tree->right,outfile,indent+2);
4680 fprintf(outfile,"OROR (%p) type (",tree);
4681 printTypeChain(tree->ftype,outfile);
4682 fprintf(outfile,")\n");
4683 ast_print(tree->left,outfile,indent+2);
4684 ast_print(tree->right,outfile,indent+2);
4687 /*------------------------------------------------------------------*/
4688 /*----------------------------*/
4689 /* comparison operators */
4690 /*----------------------------*/
4692 fprintf(outfile,"GT(>) (%p) type (",tree);
4693 printTypeChain(tree->ftype,outfile);
4694 fprintf(outfile,")\n");
4695 ast_print(tree->left,outfile,indent+2);
4696 ast_print(tree->right,outfile,indent+2);
4699 fprintf(outfile,"LT(<) (%p) type (",tree);
4700 printTypeChain(tree->ftype,outfile);
4701 fprintf(outfile,")\n");
4702 ast_print(tree->left,outfile,indent+2);
4703 ast_print(tree->right,outfile,indent+2);
4706 fprintf(outfile,"LE(<=) (%p) type (",tree);
4707 printTypeChain(tree->ftype,outfile);
4708 fprintf(outfile,")\n");
4709 ast_print(tree->left,outfile,indent+2);
4710 ast_print(tree->right,outfile,indent+2);
4713 fprintf(outfile,"GE(>=) (%p) type (",tree);
4714 printTypeChain(tree->ftype,outfile);
4715 fprintf(outfile,")\n");
4716 ast_print(tree->left,outfile,indent+2);
4717 ast_print(tree->right,outfile,indent+2);
4720 fprintf(outfile,"EQ(==) (%p) type (",tree);
4721 printTypeChain(tree->ftype,outfile);
4722 fprintf(outfile,")\n");
4723 ast_print(tree->left,outfile,indent+2);
4724 ast_print(tree->right,outfile,indent+2);
4727 fprintf(outfile,"NE(!=) (%p) type (",tree);
4728 printTypeChain(tree->ftype,outfile);
4729 fprintf(outfile,")\n");
4730 ast_print(tree->left,outfile,indent+2);
4731 ast_print(tree->right,outfile,indent+2);
4732 /*------------------------------------------------------------------*/
4733 /*----------------------------*/
4735 /*----------------------------*/
4736 case SIZEOF: /* evaluate wihout code generation */
4737 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4740 /*------------------------------------------------------------------*/
4741 /*----------------------------*/
4742 /* conditional operator '?' */
4743 /*----------------------------*/
4745 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4746 printTypeChain(tree->ftype,outfile);
4747 fprintf(outfile,")\n");
4748 ast_print(tree->left,outfile,indent+2);
4749 ast_print(tree->right,outfile,indent+2);
4753 fprintf(outfile,"COLON(:) (%p) type (",tree);
4754 printTypeChain(tree->ftype,outfile);
4755 fprintf(outfile,")\n");
4756 ast_print(tree->left,outfile,indent+2);
4757 ast_print(tree->right,outfile,indent+2);
4760 /*------------------------------------------------------------------*/
4761 /*----------------------------*/
4762 /* assignment operators */
4763 /*----------------------------*/
4765 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4766 printTypeChain(tree->ftype,outfile);
4767 fprintf(outfile,")\n");
4768 ast_print(tree->left,outfile,indent+2);
4769 ast_print(tree->right,outfile,indent+2);
4772 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4773 printTypeChain(tree->ftype,outfile);
4774 fprintf(outfile,")\n");
4775 ast_print(tree->left,outfile,indent+2);
4776 ast_print(tree->right,outfile,indent+2);
4779 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4780 printTypeChain(tree->ftype,outfile);
4781 fprintf(outfile,")\n");
4782 ast_print(tree->left,outfile,indent+2);
4783 ast_print(tree->right,outfile,indent+2);
4786 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4787 printTypeChain(tree->ftype,outfile);
4788 fprintf(outfile,")\n");
4789 ast_print(tree->left,outfile,indent+2);
4790 ast_print(tree->right,outfile,indent+2);
4793 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4794 printTypeChain(tree->ftype,outfile);
4795 fprintf(outfile,")\n");
4796 ast_print(tree->left,outfile,indent+2);
4797 ast_print(tree->right,outfile,indent+2);
4800 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4801 printTypeChain(tree->ftype,outfile);
4802 fprintf(outfile,")\n");
4803 ast_print(tree->left,outfile,indent+2);
4804 ast_print(tree->right,outfile,indent+2);
4807 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4808 printTypeChain(tree->ftype,outfile);
4809 fprintf(outfile,")\n");
4810 ast_print(tree->left,outfile,indent+2);
4811 ast_print(tree->right,outfile,indent+2);
4813 /*------------------------------------------------------------------*/
4814 /*----------------------------*/
4816 /*----------------------------*/
4818 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4819 printTypeChain(tree->ftype,outfile);
4820 fprintf(outfile,")\n");
4821 ast_print(tree->left,outfile,indent+2);
4822 ast_print(tree->right,outfile,indent+2);
4824 /*------------------------------------------------------------------*/
4825 /*----------------------------*/
4827 /*----------------------------*/
4829 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4830 printTypeChain(tree->ftype,outfile);
4831 fprintf(outfile,")\n");
4832 ast_print(tree->left,outfile,indent+2);
4833 ast_print(tree->right,outfile,indent+2);
4835 /*------------------------------------------------------------------*/
4836 /*----------------------------*/
4837 /* straight assignemnt */
4838 /*----------------------------*/
4840 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4841 printTypeChain(tree->ftype,outfile);
4842 fprintf(outfile,")\n");
4843 ast_print(tree->left,outfile,indent+2);
4844 ast_print(tree->right,outfile,indent+2);
4846 /*------------------------------------------------------------------*/
4847 /*----------------------------*/
4848 /* comma operator */
4849 /*----------------------------*/
4851 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4852 printTypeChain(tree->ftype,outfile);
4853 fprintf(outfile,")\n");
4854 ast_print(tree->left,outfile,indent+2);
4855 ast_print(tree->right,outfile,indent+2);
4857 /*------------------------------------------------------------------*/
4858 /*----------------------------*/
4860 /*----------------------------*/
4863 fprintf(outfile,"CALL (%p) type (",tree);
4864 printTypeChain(tree->ftype,outfile);
4865 fprintf(outfile,")\n");
4866 ast_print(tree->left,outfile,indent+2);
4867 ast_print(tree->right,outfile,indent+2);
4870 fprintf(outfile,"PARMS\n");
4871 ast_print(tree->left,outfile,indent+2);
4872 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4873 ast_print(tree->right,outfile,indent+2);
4876 /*------------------------------------------------------------------*/
4877 /*----------------------------*/
4878 /* return statement */
4879 /*----------------------------*/
4881 fprintf(outfile,"RETURN (%p) type (",tree);
4883 printTypeChain(tree->right->ftype,outfile);
4885 fprintf(outfile,")\n");
4886 ast_print(tree->right,outfile,indent+2);
4888 /*------------------------------------------------------------------*/
4889 /*----------------------------*/
4890 /* label statement */
4891 /*----------------------------*/
4893 fprintf(outfile,"LABEL (%p)\n",tree);
4894 ast_print(tree->left,outfile,indent+2);
4895 ast_print(tree->right,outfile,indent);
4897 /*------------------------------------------------------------------*/
4898 /*----------------------------*/
4899 /* switch statement */
4900 /*----------------------------*/
4904 fprintf(outfile,"SWITCH (%p) ",tree);
4905 ast_print(tree->left,outfile,0);
4906 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4907 INDENT(indent+2,outfile);
4908 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4909 (int) floatFromVal(val),
4910 tree->values.switchVals.swNum,
4911 (int) floatFromVal(val));
4913 ast_print(tree->right,outfile,indent);
4916 /*------------------------------------------------------------------*/
4917 /*----------------------------*/
4919 /*----------------------------*/
4921 fprintf(outfile,"IF (%p) \n",tree);
4922 ast_print(tree->left,outfile,indent+2);
4923 if (tree->trueLabel) {
4924 INDENT(indent,outfile);
4925 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4927 if (tree->falseLabel) {
4928 INDENT(indent,outfile);
4929 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4931 ast_print(tree->right,outfile,indent+2);
4933 /*------------------------------------------------------------------*/
4934 /*----------------------------*/
4936 /*----------------------------*/
4938 fprintf(outfile,"FOR (%p) \n",tree);
4939 if (AST_FOR( tree, initExpr)) {
4940 INDENT(indent+2,outfile);
4941 fprintf(outfile,"INIT EXPR ");
4942 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4944 if (AST_FOR( tree, condExpr)) {
4945 INDENT(indent+2,outfile);
4946 fprintf(outfile,"COND EXPR ");
4947 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4949 if (AST_FOR( tree, loopExpr)) {
4950 INDENT(indent+2,outfile);
4951 fprintf(outfile,"LOOP EXPR ");
4952 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4954 fprintf(outfile,"FOR LOOP BODY \n");
4955 ast_print(tree->left,outfile,indent+2);
4964 ast_print(t,stdout,0);