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 return (IS_AST_LIT_VALUE(cexpr));
1167 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1168 "unexpected link in expression tree\n");
1171 if (cexpr->opval.op==CAST) {
1172 // jwk: cast ignored, maybe we should throw a warning here
1173 return constExprTree(cexpr->right);
1175 if (cexpr->opval.op=='&') {
1178 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1181 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1188 /*-----------------------------------------------------------------*/
1189 /* constExprValue - returns the value of a constant expression */
1190 /* or NULL if it is not a constant expression */
1191 /*-----------------------------------------------------------------*/
1193 constExprValue (ast * cexpr, int check)
1195 cexpr = decorateType (resolveSymbols (cexpr));
1197 /* if this is not a constant then */
1198 if (!IS_LITERAL (cexpr->ftype))
1200 /* then check if this is a literal array
1202 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1203 SPEC_CVAL (cexpr->etype).v_char &&
1204 IS_ARRAY (cexpr->ftype))
1206 value *val = valFromType (cexpr->ftype);
1207 SPEC_SCLS (val->etype) = S_LITERAL;
1208 val->sym = cexpr->opval.val->sym;
1209 val->sym->type = copyLinkChain (cexpr->ftype);
1210 val->sym->etype = getSpec (val->sym->type);
1211 strcpy (val->name, cexpr->opval.val->sym->rname);
1215 /* if we are casting a literal value then */
1216 if (IS_AST_OP (cexpr) &&
1217 cexpr->opval.op == CAST &&
1218 IS_LITERAL (cexpr->left->ftype))
1219 return valCastLiteral (cexpr->ftype,
1220 floatFromVal (cexpr->left->opval.val));
1222 if (IS_AST_VALUE (cexpr))
1223 return cexpr->opval.val;
1226 werror (E_CONST_EXPECTED, "found expression");
1231 /* return the value */
1232 return cexpr->opval.val;
1236 /*-----------------------------------------------------------------*/
1237 /* isLabelInAst - will return true if a given label is found */
1238 /*-----------------------------------------------------------------*/
1240 isLabelInAst (symbol * label, ast * tree)
1242 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1245 if (IS_AST_OP (tree) &&
1246 tree->opval.op == LABEL &&
1247 isSymbolEqual (AST_SYMBOL (tree->left), label))
1250 return isLabelInAst (label, tree->right) &&
1251 isLabelInAst (label, tree->left);
1255 /*-----------------------------------------------------------------*/
1256 /* isLoopCountable - return true if the loop count can be determi- */
1257 /* -ned at compile time . */
1258 /*-----------------------------------------------------------------*/
1260 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1261 symbol ** sym, ast ** init, ast ** end)
1264 /* the loop is considered countable if the following
1265 conditions are true :-
1267 a) initExpr :- <sym> = <const>
1268 b) condExpr :- <sym> < <const1>
1269 c) loopExpr :- <sym> ++
1272 /* first check the initExpr */
1273 if (IS_AST_OP (initExpr) &&
1274 initExpr->opval.op == '=' && /* is assignment */
1275 IS_AST_SYM_VALUE (initExpr->left))
1276 { /* left is a symbol */
1278 *sym = AST_SYMBOL (initExpr->left);
1279 *init = initExpr->right;
1284 /* for now the symbol has to be of
1286 if (!IS_INTEGRAL ((*sym)->type))
1289 /* now check condExpr */
1290 if (IS_AST_OP (condExpr))
1293 switch (condExpr->opval.op)
1296 if (IS_AST_SYM_VALUE (condExpr->left) &&
1297 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1298 IS_AST_LIT_VALUE (condExpr->right))
1300 *end = condExpr->right;
1306 if (IS_AST_OP (condExpr->left) &&
1307 condExpr->left->opval.op == '>' &&
1308 IS_AST_LIT_VALUE (condExpr->left->right) &&
1309 IS_AST_SYM_VALUE (condExpr->left->left) &&
1310 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1313 *end = newNode ('+', condExpr->left->right,
1314 newAst_VALUE (constVal ("1")));
1325 /* check loop expression is of the form <sym>++ */
1326 if (!IS_AST_OP (loopExpr))
1329 /* check if <sym> ++ */
1330 if (loopExpr->opval.op == INC_OP)
1336 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1337 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1344 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1345 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1353 if (loopExpr->opval.op == ADD_ASSIGN)
1356 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1357 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1358 IS_AST_LIT_VALUE (loopExpr->right) &&
1359 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1367 /*-----------------------------------------------------------------*/
1368 /* astHasVolatile - returns true if ast contains any volatile */
1369 /*-----------------------------------------------------------------*/
1371 astHasVolatile (ast * tree)
1376 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1379 if (IS_AST_OP (tree))
1380 return astHasVolatile (tree->left) ||
1381 astHasVolatile (tree->right);
1386 /*-----------------------------------------------------------------*/
1387 /* astHasPointer - return true if the ast contains any ptr variable */
1388 /*-----------------------------------------------------------------*/
1390 astHasPointer (ast * tree)
1395 if (IS_AST_LINK (tree))
1398 /* if we hit an array expression then check
1399 only the left side */
1400 if (IS_AST_OP (tree) && tree->opval.op == '[')
1401 return astHasPointer (tree->left);
1403 if (IS_AST_VALUE (tree))
1404 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1406 return astHasPointer (tree->left) ||
1407 astHasPointer (tree->right);
1411 /*-----------------------------------------------------------------*/
1412 /* astHasSymbol - return true if the ast has the given symbol */
1413 /*-----------------------------------------------------------------*/
1415 astHasSymbol (ast * tree, symbol * sym)
1417 if (!tree || IS_AST_LINK (tree))
1420 if (IS_AST_VALUE (tree))
1422 if (IS_AST_SYM_VALUE (tree))
1423 return isSymbolEqual (AST_SYMBOL (tree), sym);
1428 return astHasSymbol (tree->left, sym) ||
1429 astHasSymbol (tree->right, sym);
1432 /*-----------------------------------------------------------------*/
1433 /* astHasDeref - return true if the ast has an indirect access */
1434 /*-----------------------------------------------------------------*/
1436 astHasDeref (ast * tree)
1438 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1441 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1443 return astHasDeref (tree->left) || astHasDeref (tree->right);
1446 /*-----------------------------------------------------------------*/
1447 /* isConformingBody - the loop body has to conform to a set of rules */
1448 /* for the loop to be considered reversible read on for rules */
1449 /*-----------------------------------------------------------------*/
1451 isConformingBody (ast * pbody, symbol * sym, ast * body)
1454 /* we are going to do a pre-order traversal of the
1455 tree && check for the following conditions. (essentially
1456 a set of very shallow tests )
1457 a) the sym passed does not participate in
1458 any arithmetic operation
1459 b) There are no function calls
1460 c) all jumps are within the body
1461 d) address of loop control variable not taken
1462 e) if an assignment has a pointer on the
1463 left hand side make sure right does not have
1464 loop control variable */
1466 /* if we reach the end or a leaf then true */
1467 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1471 /* if anything else is "volatile" */
1472 if (IS_VOLATILE (TETYPE (pbody)))
1475 /* we will walk the body in a pre-order traversal for
1477 switch (pbody->opval.op)
1479 /*------------------------------------------------------------------*/
1481 return isConformingBody (pbody->right, sym, body);
1483 /*------------------------------------------------------------------*/
1488 /*------------------------------------------------------------------*/
1489 case INC_OP: /* incerement operator unary so left only */
1492 /* sure we are not sym is not modified */
1494 IS_AST_SYM_VALUE (pbody->left) &&
1495 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1499 IS_AST_SYM_VALUE (pbody->right) &&
1500 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1505 /*------------------------------------------------------------------*/
1507 case '*': /* can be unary : if right is null then unary operation */
1512 /* if right is NULL then unary operation */
1513 /*------------------------------------------------------------------*/
1514 /*----------------------------*/
1516 /*----------------------------*/
1519 if (IS_AST_SYM_VALUE (pbody->left) &&
1520 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1523 return isConformingBody (pbody->left, sym, body);
1527 if (astHasSymbol (pbody->left, sym) ||
1528 astHasSymbol (pbody->right, sym))
1533 /*------------------------------------------------------------------*/
1541 if (IS_AST_SYM_VALUE (pbody->left) &&
1542 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1545 if (IS_AST_SYM_VALUE (pbody->right) &&
1546 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1549 return isConformingBody (pbody->left, sym, body) &&
1550 isConformingBody (pbody->right, sym, body);
1557 if (IS_AST_SYM_VALUE (pbody->left) &&
1558 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1560 return isConformingBody (pbody->left, sym, body);
1562 /*------------------------------------------------------------------*/
1574 case SIZEOF: /* evaluate wihout code generation */
1576 return isConformingBody (pbody->left, sym, body) &&
1577 isConformingBody (pbody->right, sym, body);
1579 /*------------------------------------------------------------------*/
1582 /* if left has a pointer & right has loop
1583 control variable then we cannot */
1584 if (astHasPointer (pbody->left) &&
1585 astHasSymbol (pbody->right, sym))
1587 if (astHasVolatile (pbody->left))
1590 if (IS_AST_SYM_VALUE (pbody->left) &&
1591 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1594 if (astHasVolatile (pbody->left))
1597 if (astHasDeref(pbody->right)) return FALSE;
1599 return isConformingBody (pbody->left, sym, body) &&
1600 isConformingBody (pbody->right, sym, body);
1611 assert ("Parser should not have generated this\n");
1613 /*------------------------------------------------------------------*/
1614 /*----------------------------*/
1615 /* comma operator */
1616 /*----------------------------*/
1618 return isConformingBody (pbody->left, sym, body) &&
1619 isConformingBody (pbody->right, sym, body);
1621 /*------------------------------------------------------------------*/
1622 /*----------------------------*/
1624 /*----------------------------*/
1628 /*------------------------------------------------------------------*/
1629 /*----------------------------*/
1630 /* return statement */
1631 /*----------------------------*/
1636 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1641 if (astHasSymbol (pbody->left, sym))
1648 return isConformingBody (pbody->left, sym, body) &&
1649 isConformingBody (pbody->right, sym, body);
1655 /*-----------------------------------------------------------------*/
1656 /* isLoopReversible - takes a for loop as input && returns true */
1657 /* if the for loop is reversible. If yes will set the value of */
1658 /* the loop control var & init value & termination value */
1659 /*-----------------------------------------------------------------*/
1661 isLoopReversible (ast * loop, symbol ** loopCntrl,
1662 ast ** init, ast ** end)
1664 /* if option says don't do it then don't */
1665 if (optimize.noLoopReverse)
1667 /* there are several tests to determine this */
1669 /* for loop has to be of the form
1670 for ( <sym> = <const1> ;
1671 [<sym> < <const2>] ;
1672 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1674 if (!isLoopCountable (AST_FOR (loop, initExpr),
1675 AST_FOR (loop, condExpr),
1676 AST_FOR (loop, loopExpr),
1677 loopCntrl, init, end))
1680 /* now do some serious checking on the body of the loop
1683 return isConformingBody (loop->left, *loopCntrl, loop->left);
1687 /*-----------------------------------------------------------------*/
1688 /* replLoopSym - replace the loop sym by loop sym -1 */
1689 /*-----------------------------------------------------------------*/
1691 replLoopSym (ast * body, symbol * sym)
1694 if (!body || IS_AST_LINK (body))
1697 if (IS_AST_SYM_VALUE (body))
1700 if (isSymbolEqual (AST_SYMBOL (body), sym))
1704 body->opval.op = '-';
1705 body->left = newAst_VALUE (symbolVal (sym));
1706 body->right = newAst_VALUE (constVal ("1"));
1714 replLoopSym (body->left, sym);
1715 replLoopSym (body->right, sym);
1719 /*-----------------------------------------------------------------*/
1720 /* reverseLoop - do the actual loop reversal */
1721 /*-----------------------------------------------------------------*/
1723 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1727 /* create the following tree
1732 if (sym) goto for_continue ;
1735 /* put it together piece by piece */
1736 rloop = newNode (NULLOP,
1737 createIf (newAst_VALUE (symbolVal (sym)),
1739 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1742 newAst_VALUE (symbolVal (sym)),
1745 replLoopSym (loop->left, sym);
1747 rloop = newNode (NULLOP,
1749 newAst_VALUE (symbolVal (sym)),
1750 newNode ('-', end, init)),
1751 createLabel (AST_FOR (loop, continueLabel),
1755 newNode (SUB_ASSIGN,
1756 newAst_VALUE (symbolVal (sym)),
1757 newAst_VALUE (constVal ("1"))),
1760 return decorateType (rloop);
1764 /*-----------------------------------------------------------------*/
1765 /* decorateType - compute type for this tree also does type cheking */
1766 /* this is done bottom up, since type have to flow upwards */
1767 /* it also does constant folding, and paramater checking */
1768 /*-----------------------------------------------------------------*/
1770 decorateType (ast * tree)
1778 /* if already has type then do nothing */
1779 if (tree->decorated)
1782 tree->decorated = 1;
1784 /* print the line */
1785 /* if not block & function */
1786 if (tree->type == EX_OP &&
1787 (tree->opval.op != FUNCTION &&
1788 tree->opval.op != BLOCK &&
1789 tree->opval.op != NULLOP))
1791 filename = tree->filename;
1792 lineno = tree->lineno;
1795 /* if any child is an error | this one is an error do nothing */
1796 if (tree->isError ||
1797 (tree->left && tree->left->isError) ||
1798 (tree->right && tree->right->isError))
1801 /*------------------------------------------------------------------*/
1802 /*----------------------------*/
1803 /* leaf has been reached */
1804 /*----------------------------*/
1805 /* if this is of type value */
1806 /* just get the type */
1807 if (tree->type == EX_VALUE)
1810 if (IS_LITERAL (tree->opval.val->etype))
1813 /* if this is a character array then declare it */
1814 if (IS_ARRAY (tree->opval.val->type))
1815 tree->opval.val = stringToSymbol (tree->opval.val);
1817 /* otherwise just copy the type information */
1818 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1822 if (tree->opval.val->sym)
1824 /* if the undefined flag is set then give error message */
1825 if (tree->opval.val->sym->undefined)
1827 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1829 TTYPE (tree) = TETYPE (tree) =
1830 tree->opval.val->type = tree->opval.val->sym->type =
1831 tree->opval.val->etype = tree->opval.val->sym->etype =
1832 copyLinkChain (INTTYPE);
1837 /* if impilicit i.e. struct/union member then no type */
1838 if (tree->opval.val->sym->implicit)
1839 TTYPE (tree) = TETYPE (tree) = NULL;
1844 /* else copy the type */
1845 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1847 /* and mark it as referenced */
1848 tree->opval.val->sym->isref = 1;
1856 /* if type link for the case of cast */
1857 if (tree->type == EX_LINK)
1859 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1866 dtl = decorateType (tree->left);
1867 /* delay right side for '?' operator since conditional macro expansions might
1869 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1871 /* this is to take care of situations
1872 when the tree gets rewritten */
1873 if (dtl != tree->left)
1875 if (dtr != tree->right)
1879 /* depending on type of operator do */
1881 switch (tree->opval.op)
1883 /*------------------------------------------------------------------*/
1884 /*----------------------------*/
1886 /*----------------------------*/
1889 /* determine which is the array & which the index */
1890 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1893 ast *tempTree = tree->left;
1894 tree->left = tree->right;
1895 tree->right = tempTree;
1898 /* first check if this is a array or a pointer */
1899 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1901 werror (E_NEED_ARRAY_PTR, "[]");
1902 goto errorTreeReturn;
1905 /* check if the type of the idx */
1906 if (!IS_INTEGRAL (RTYPE (tree)))
1908 werror (E_IDX_NOT_INT);
1909 goto errorTreeReturn;
1912 /* if the left is an rvalue then error */
1915 werror (E_LVALUE_REQUIRED, "array access");
1916 goto errorTreeReturn;
1919 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1920 if (IS_PTR(LTYPE(tree))) {
1921 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1925 /*------------------------------------------------------------------*/
1926 /*----------------------------*/
1928 /*----------------------------*/
1930 /* if this is not a structure */
1931 if (!IS_STRUCT (LTYPE (tree)))
1933 werror (E_STRUCT_UNION, ".");
1934 goto errorTreeReturn;
1936 TTYPE (tree) = structElemType (LTYPE (tree),
1937 (tree->right->type == EX_VALUE ?
1938 tree->right->opval.val : NULL));
1939 TETYPE (tree) = getSpec (TTYPE (tree));
1942 /*------------------------------------------------------------------*/
1943 /*----------------------------*/
1944 /* struct/union pointer */
1945 /*----------------------------*/
1947 /* if not pointer to a structure */
1948 if (!IS_PTR (LTYPE (tree)))
1950 werror (E_PTR_REQD);
1951 goto errorTreeReturn;
1954 if (!IS_STRUCT (LTYPE (tree)->next))
1956 werror (E_STRUCT_UNION, "->");
1957 goto errorTreeReturn;
1960 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1961 (tree->right->type == EX_VALUE ?
1962 tree->right->opval.val : NULL));
1963 TETYPE (tree) = getSpec (TTYPE (tree));
1965 /* adjust the storage class */
1966 switch (DCL_TYPE(tree->left->ftype)) {
1970 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
1973 SPEC_SCLS(TETYPE(tree)) = S_CODE;
1978 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
1981 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
1984 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
1993 /*------------------------------------------------------------------*/
1994 /*----------------------------*/
1995 /* ++/-- operation */
1996 /*----------------------------*/
1997 case INC_OP: /* incerement operator unary so left only */
2000 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2001 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2002 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2003 werror (E_CODE_WRITE, "++/--");
2012 /*------------------------------------------------------------------*/
2013 /*----------------------------*/
2015 /*----------------------------*/
2016 case '&': /* can be unary */
2017 /* if right is NULL then unary operation */
2018 if (tree->right) /* not an unary operation */
2021 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2023 werror (E_BITWISE_OP);
2024 werror (W_CONTINUE, "left & right types are ");
2025 printTypeChain (LTYPE (tree), stderr);
2026 fprintf (stderr, ",");
2027 printTypeChain (RTYPE (tree), stderr);
2028 fprintf (stderr, "\n");
2029 goto errorTreeReturn;
2032 /* if they are both literal */
2033 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2035 tree->type = EX_VALUE;
2036 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2037 valFromType (RETYPE (tree)), '&');
2039 tree->right = tree->left = NULL;
2040 TETYPE (tree) = tree->opval.val->etype;
2041 TTYPE (tree) = tree->opval.val->type;
2045 /* see if this is a GETHBIT operation if yes
2048 ast *otree = optimizeGetHbit (tree);
2051 return decorateType (otree);
2055 computeType (LTYPE (tree), RTYPE (tree));
2056 TETYPE (tree) = getSpec (TTYPE (tree));
2058 LRVAL (tree) = RRVAL (tree) = 1;
2062 /*------------------------------------------------------------------*/
2063 /*----------------------------*/
2065 /*----------------------------*/
2067 p->class = DECLARATOR;
2068 /* if bit field then error */
2069 if (IS_BITVAR (tree->left->etype))
2071 werror (E_ILLEGAL_ADDR, "address of bit variable");
2072 goto errorTreeReturn;
2075 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2077 werror (E_ILLEGAL_ADDR, "address of register variable");
2078 goto errorTreeReturn;
2081 if (IS_FUNC (LTYPE (tree)))
2083 werror (E_ILLEGAL_ADDR, "address of function");
2084 goto errorTreeReturn;
2087 if (IS_LITERAL(LTYPE(tree)))
2089 werror (E_ILLEGAL_ADDR, "address of literal");
2090 goto errorTreeReturn;
2095 werror (E_LVALUE_REQUIRED, "address of");
2096 goto errorTreeReturn;
2098 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2100 DCL_TYPE (p) = CPOINTER;
2101 DCL_PTR_CONST (p) = port->mem.code_ro;
2103 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2104 DCL_TYPE (p) = FPOINTER;
2105 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2106 DCL_TYPE (p) = PPOINTER;
2107 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2108 DCL_TYPE (p) = IPOINTER;
2109 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2110 DCL_TYPE (p) = EEPPOINTER;
2111 else if (SPEC_OCLS(tree->left->etype))
2112 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2114 DCL_TYPE (p) = POINTER;
2116 if (IS_AST_SYM_VALUE (tree->left))
2118 AST_SYMBOL (tree->left)->addrtaken = 1;
2119 AST_SYMBOL (tree->left)->allocreq = 1;
2122 p->next = LTYPE (tree);
2124 TETYPE (tree) = getSpec (TTYPE (tree));
2125 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2126 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2131 /*------------------------------------------------------------------*/
2132 /*----------------------------*/
2134 /*----------------------------*/
2136 /* if the rewrite succeeds then don't go any furthur */
2138 ast *wtree = optimizeRRCRLC (tree);
2140 return decorateType (wtree);
2142 /*------------------------------------------------------------------*/
2143 /*----------------------------*/
2145 /*----------------------------*/
2147 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2149 werror (E_BITWISE_OP);
2150 werror (W_CONTINUE, "left & right types are ");
2151 printTypeChain (LTYPE (tree), stderr);
2152 fprintf (stderr, ",");
2153 printTypeChain (RTYPE (tree), stderr);
2154 fprintf (stderr, "\n");
2155 goto errorTreeReturn;
2158 /* if they are both literal then */
2159 /* rewrite the tree */
2160 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2162 tree->type = EX_VALUE;
2163 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2164 valFromType (RETYPE (tree)),
2166 tree->right = tree->left = NULL;
2167 TETYPE (tree) = tree->opval.val->etype;
2168 TTYPE (tree) = tree->opval.val->type;
2171 LRVAL (tree) = RRVAL (tree) = 1;
2172 TETYPE (tree) = getSpec (TTYPE (tree) =
2173 computeType (LTYPE (tree),
2176 /*------------------------------------------------------------------*/
2177 /*----------------------------*/
2179 /*----------------------------*/
2181 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2183 werror (E_INVALID_OP, "divide");
2184 goto errorTreeReturn;
2186 /* if they are both literal then */
2187 /* rewrite the tree */
2188 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2190 tree->type = EX_VALUE;
2191 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2192 valFromType (RETYPE (tree)));
2193 tree->right = tree->left = NULL;
2194 TETYPE (tree) = getSpec (TTYPE (tree) =
2195 tree->opval.val->type);
2198 LRVAL (tree) = RRVAL (tree) = 1;
2199 TETYPE (tree) = getSpec (TTYPE (tree) =
2200 computeType (LTYPE (tree),
2204 /*------------------------------------------------------------------*/
2205 /*----------------------------*/
2207 /*----------------------------*/
2209 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2211 werror (E_BITWISE_OP);
2212 werror (W_CONTINUE, "left & right types are ");
2213 printTypeChain (LTYPE (tree), stderr);
2214 fprintf (stderr, ",");
2215 printTypeChain (RTYPE (tree), stderr);
2216 fprintf (stderr, "\n");
2217 goto errorTreeReturn;
2219 /* if they are both literal then */
2220 /* rewrite the tree */
2221 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2223 tree->type = EX_VALUE;
2224 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2225 valFromType (RETYPE (tree)));
2226 tree->right = tree->left = NULL;
2227 TETYPE (tree) = getSpec (TTYPE (tree) =
2228 tree->opval.val->type);
2231 LRVAL (tree) = RRVAL (tree) = 1;
2232 TETYPE (tree) = getSpec (TTYPE (tree) =
2233 computeType (LTYPE (tree),
2237 /*------------------------------------------------------------------*/
2238 /*----------------------------*/
2239 /* address dereference */
2240 /*----------------------------*/
2241 case '*': /* can be unary : if right is null then unary operation */
2244 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2246 werror (E_PTR_REQD);
2247 goto errorTreeReturn;
2252 werror (E_LVALUE_REQUIRED, "pointer deref");
2253 goto errorTreeReturn;
2255 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2256 LTYPE (tree)->next : NULL);
2257 TETYPE (tree) = getSpec (TTYPE (tree));
2258 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2262 /*------------------------------------------------------------------*/
2263 /*----------------------------*/
2264 /* multiplication */
2265 /*----------------------------*/
2266 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2268 werror (E_INVALID_OP, "multiplication");
2269 goto errorTreeReturn;
2272 /* if they are both literal then */
2273 /* rewrite the tree */
2274 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2276 tree->type = EX_VALUE;
2277 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2278 valFromType (RETYPE (tree)));
2279 tree->right = tree->left = NULL;
2280 TETYPE (tree) = getSpec (TTYPE (tree) =
2281 tree->opval.val->type);
2285 /* if left is a literal exchange left & right */
2286 if (IS_LITERAL (LTYPE (tree)))
2288 ast *tTree = tree->left;
2289 tree->left = tree->right;
2290 tree->right = tTree;
2293 LRVAL (tree) = RRVAL (tree) = 1;
2294 /* promote result to int if left & right are char
2295 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2296 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2297 TETYPE (tree) = getSpec (TTYPE (tree) =
2298 computeType (LTYPE (tree),
2300 SPEC_NOUN(TETYPE(tree)) = V_INT;
2302 TETYPE (tree) = getSpec (TTYPE (tree) =
2303 computeType (LTYPE (tree),
2308 /*------------------------------------------------------------------*/
2309 /*----------------------------*/
2310 /* unary '+' operator */
2311 /*----------------------------*/
2316 if (!IS_INTEGRAL (LTYPE (tree)))
2318 werror (E_UNARY_OP, '+');
2319 goto errorTreeReturn;
2322 /* if left is a literal then do it */
2323 if (IS_LITERAL (LTYPE (tree)))
2325 tree->type = EX_VALUE;
2326 tree->opval.val = valFromType (LETYPE (tree));
2328 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2332 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2336 /*------------------------------------------------------------------*/
2337 /*----------------------------*/
2339 /*----------------------------*/
2341 /* this is not a unary operation */
2342 /* if both pointers then problem */
2343 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2344 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2346 werror (E_PTR_PLUS_PTR);
2347 goto errorTreeReturn;
2350 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2351 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2353 werror (E_PLUS_INVALID, "+");
2354 goto errorTreeReturn;
2357 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2358 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2360 werror (E_PLUS_INVALID, "+");
2361 goto errorTreeReturn;
2363 /* if they are both literal then */
2364 /* rewrite the tree */
2365 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2367 tree->type = EX_VALUE;
2368 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2369 valFromType (RETYPE (tree)));
2370 tree->right = tree->left = NULL;
2371 TETYPE (tree) = getSpec (TTYPE (tree) =
2372 tree->opval.val->type);
2376 /* if the right is a pointer or left is a literal
2377 xchange left & right */
2378 if (IS_ARRAY (RTYPE (tree)) ||
2379 IS_PTR (RTYPE (tree)) ||
2380 IS_LITERAL (LTYPE (tree)))
2382 ast *tTree = tree->left;
2383 tree->left = tree->right;
2384 tree->right = tTree;
2387 LRVAL (tree) = RRVAL (tree) = 1;
2388 /* if the left is a pointer */
2389 if (IS_PTR (LTYPE (tree)))
2390 TETYPE (tree) = getSpec (TTYPE (tree) =
2393 TETYPE (tree) = getSpec (TTYPE (tree) =
2394 computeType (LTYPE (tree),
2398 /*------------------------------------------------------------------*/
2399 /*----------------------------*/
2401 /*----------------------------*/
2402 case '-': /* can be unary */
2403 /* if right is null then unary */
2407 if (!IS_ARITHMETIC (LTYPE (tree)))
2409 werror (E_UNARY_OP, tree->opval.op);
2410 goto errorTreeReturn;
2413 /* if left is a literal then do it */
2414 if (IS_LITERAL (LTYPE (tree)))
2416 tree->type = EX_VALUE;
2417 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2419 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2420 SPEC_USIGN(TETYPE(tree)) = 0;
2424 TTYPE (tree) = LTYPE (tree);
2428 /*------------------------------------------------------------------*/
2429 /*----------------------------*/
2431 /*----------------------------*/
2433 if (!(IS_PTR (LTYPE (tree)) ||
2434 IS_ARRAY (LTYPE (tree)) ||
2435 IS_ARITHMETIC (LTYPE (tree))))
2437 werror (E_PLUS_INVALID, "-");
2438 goto errorTreeReturn;
2441 if (!(IS_PTR (RTYPE (tree)) ||
2442 IS_ARRAY (RTYPE (tree)) ||
2443 IS_ARITHMETIC (RTYPE (tree))))
2445 werror (E_PLUS_INVALID, "-");
2446 goto errorTreeReturn;
2449 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2450 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2451 IS_INTEGRAL (RTYPE (tree))))
2453 werror (E_PLUS_INVALID, "-");
2454 goto errorTreeReturn;
2457 /* if they are both literal then */
2458 /* rewrite the tree */
2459 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2461 tree->type = EX_VALUE;
2462 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2463 valFromType (RETYPE (tree)));
2464 tree->right = tree->left = NULL;
2465 TETYPE (tree) = getSpec (TTYPE (tree) =
2466 tree->opval.val->type);
2470 /* if the left & right are equal then zero */
2471 if (isAstEqual (tree->left, tree->right))
2473 tree->type = EX_VALUE;
2474 tree->left = tree->right = NULL;
2475 tree->opval.val = constVal ("0");
2476 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2480 /* if both of them are pointers or arrays then */
2481 /* the result is going to be an integer */
2482 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2483 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2484 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2486 /* if only the left is a pointer */
2487 /* then result is a pointer */
2488 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2489 TETYPE (tree) = getSpec (TTYPE (tree) =
2492 TETYPE (tree) = getSpec (TTYPE (tree) =
2493 computeType (LTYPE (tree),
2495 LRVAL (tree) = RRVAL (tree) = 1;
2498 /*------------------------------------------------------------------*/
2499 /*----------------------------*/
2501 /*----------------------------*/
2503 /* can be only integral type */
2504 if (!IS_INTEGRAL (LTYPE (tree)))
2506 werror (E_UNARY_OP, tree->opval.op);
2507 goto errorTreeReturn;
2510 /* if left is a literal then do it */
2511 if (IS_LITERAL (LTYPE (tree)))
2513 tree->type = EX_VALUE;
2514 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2516 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2520 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2523 /*------------------------------------------------------------------*/
2524 /*----------------------------*/
2526 /*----------------------------*/
2528 /* can be pointer */
2529 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2530 !IS_PTR (LTYPE (tree)) &&
2531 !IS_ARRAY (LTYPE (tree)))
2533 werror (E_UNARY_OP, tree->opval.op);
2534 goto errorTreeReturn;
2537 /* if left is a literal then do it */
2538 if (IS_LITERAL (LTYPE (tree)))
2540 tree->type = EX_VALUE;
2541 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2543 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2547 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2550 /*------------------------------------------------------------------*/
2551 /*----------------------------*/
2553 /*----------------------------*/
2556 TTYPE (tree) = LTYPE (tree);
2557 TETYPE (tree) = LETYPE (tree);
2561 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2566 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2568 werror (E_SHIFT_OP_INVALID);
2569 werror (W_CONTINUE, "left & right types are ");
2570 printTypeChain (LTYPE (tree), stderr);
2571 fprintf (stderr, ",");
2572 printTypeChain (RTYPE (tree), stderr);
2573 fprintf (stderr, "\n");
2574 goto errorTreeReturn;
2577 /* if they are both literal then */
2578 /* rewrite the tree */
2579 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2581 tree->type = EX_VALUE;
2582 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2583 valFromType (RETYPE (tree)),
2584 (tree->opval.op == LEFT_OP ? 1 : 0));
2585 tree->right = tree->left = NULL;
2586 TETYPE (tree) = getSpec (TTYPE (tree) =
2587 tree->opval.val->type);
2590 /* if only the right side is a literal & we are
2591 shifting more than size of the left operand then zero */
2592 if (IS_LITERAL (RTYPE (tree)) &&
2593 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2594 (getSize (LTYPE (tree)) * 8))
2596 werror (W_SHIFT_CHANGED,
2597 (tree->opval.op == LEFT_OP ? "left" : "right"));
2598 tree->type = EX_VALUE;
2599 tree->left = tree->right = NULL;
2600 tree->opval.val = constVal ("0");
2601 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2604 LRVAL (tree) = RRVAL (tree) = 1;
2605 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2607 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2611 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2615 /*------------------------------------------------------------------*/
2616 /*----------------------------*/
2618 /*----------------------------*/
2619 case CAST: /* change the type */
2620 /* cannot cast to an aggregate type */
2621 if (IS_AGGREGATE (LTYPE (tree)))
2623 werror (E_CAST_ILLEGAL);
2624 goto errorTreeReturn;
2627 /* make sure the type is complete and sane */
2628 checkTypeSanity(LETYPE(tree), "(cast)");
2631 /* if the right is a literal replace the tree */
2632 if (IS_LITERAL (RETYPE (tree))) {
2633 if (!IS_PTR (LTYPE (tree))) {
2634 tree->type = EX_VALUE;
2636 valCastLiteral (LTYPE (tree),
2637 floatFromVal (valFromType (RETYPE (tree))));
2640 TTYPE (tree) = tree->opval.val->type;
2641 tree->values.literalFromCast = 1;
2642 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2643 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2644 sym_link *rest = LTYPE(tree)->next;
2645 werror(W_LITERAL_GENERIC);
2646 TTYPE(tree) = newLink();
2647 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2648 TTYPE(tree)->next = rest;
2649 tree->left->opval.lnk = TTYPE(tree);
2652 TTYPE (tree) = LTYPE (tree);
2656 TTYPE (tree) = LTYPE (tree);
2660 /* if pointer to struct then check names */
2661 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2662 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2663 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2664 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2666 /* if the right is a literal replace the tree */
2667 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2668 tree->type = EX_VALUE;
2670 valCastLiteral (LTYPE (tree),
2671 floatFromVal (valFromType (RETYPE (tree))));
2674 TTYPE (tree) = tree->opval.val->type;
2675 tree->values.literalFromCast = 1;
2677 TTYPE (tree) = LTYPE (tree);
2681 TETYPE (tree) = getSpec (TTYPE (tree));
2685 /*------------------------------------------------------------------*/
2686 /*----------------------------*/
2687 /* logical &&, || */
2688 /*----------------------------*/
2691 /* each must me arithmetic type or be a pointer */
2692 if (!IS_PTR (LTYPE (tree)) &&
2693 !IS_ARRAY (LTYPE (tree)) &&
2694 !IS_INTEGRAL (LTYPE (tree)))
2696 werror (E_COMPARE_OP);
2697 goto errorTreeReturn;
2700 if (!IS_PTR (RTYPE (tree)) &&
2701 !IS_ARRAY (RTYPE (tree)) &&
2702 !IS_INTEGRAL (RTYPE (tree)))
2704 werror (E_COMPARE_OP);
2705 goto errorTreeReturn;
2707 /* if they are both literal then */
2708 /* rewrite the tree */
2709 if (IS_LITERAL (RTYPE (tree)) &&
2710 IS_LITERAL (LTYPE (tree)))
2712 tree->type = EX_VALUE;
2713 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2714 valFromType (RETYPE (tree)),
2716 tree->right = tree->left = NULL;
2717 TETYPE (tree) = getSpec (TTYPE (tree) =
2718 tree->opval.val->type);
2721 LRVAL (tree) = RRVAL (tree) = 1;
2722 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2725 /*------------------------------------------------------------------*/
2726 /*----------------------------*/
2727 /* comparison operators */
2728 /*----------------------------*/
2736 ast *lt = optimizeCompare (tree);
2742 /* if they are pointers they must be castable */
2743 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2745 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2747 werror (E_COMPARE_OP);
2748 fprintf (stderr, "comparing type ");
2749 printTypeChain (LTYPE (tree), stderr);
2750 fprintf (stderr, "to type ");
2751 printTypeChain (RTYPE (tree), stderr);
2752 fprintf (stderr, "\n");
2753 goto errorTreeReturn;
2756 /* else they should be promotable to one another */
2759 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2760 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2762 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2764 werror (E_COMPARE_OP);
2765 fprintf (stderr, "comparing type ");
2766 printTypeChain (LTYPE (tree), stderr);
2767 fprintf (stderr, "to type ");
2768 printTypeChain (RTYPE (tree), stderr);
2769 fprintf (stderr, "\n");
2770 goto errorTreeReturn;
2773 /* if unsigned value < 0 then always false */
2774 /* if (unsigned value) > 0 then (unsigned value) */
2775 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2776 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2778 if (tree->opval.op == '<') {
2781 if (tree->opval.op == '>') {
2785 /* if they are both literal then */
2786 /* rewrite the tree */
2787 if (IS_LITERAL (RTYPE (tree)) &&
2788 IS_LITERAL (LTYPE (tree)))
2790 tree->type = EX_VALUE;
2791 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2792 valFromType (RETYPE (tree)),
2794 tree->right = tree->left = NULL;
2795 TETYPE (tree) = getSpec (TTYPE (tree) =
2796 tree->opval.val->type);
2799 LRVAL (tree) = RRVAL (tree) = 1;
2800 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2803 /*------------------------------------------------------------------*/
2804 /*----------------------------*/
2806 /*----------------------------*/
2807 case SIZEOF: /* evaluate wihout code generation */
2808 /* change the type to a integer */
2809 tree->type = EX_VALUE;
2810 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2811 tree->opval.val = constVal (buffer);
2812 tree->right = tree->left = NULL;
2813 TETYPE (tree) = getSpec (TTYPE (tree) =
2814 tree->opval.val->type);
2817 /*------------------------------------------------------------------*/
2818 /*----------------------------*/
2820 /*----------------------------*/
2822 /* return typeof enum value */
2823 tree->type = EX_VALUE;
2826 if (IS_SPEC(tree->right->ftype)) {
2827 switch (SPEC_NOUN(tree->right->ftype)) {
2829 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2830 else typeofv = TYPEOF_INT;
2833 typeofv = TYPEOF_FLOAT;
2836 typeofv = TYPEOF_CHAR;
2839 typeofv = TYPEOF_VOID;
2842 typeofv = TYPEOF_STRUCT;
2845 typeofv = TYPEOF_BIT;
2848 typeofv = TYPEOF_SBIT;
2854 switch (DCL_TYPE(tree->right->ftype)) {
2856 typeofv = TYPEOF_POINTER;
2859 typeofv = TYPEOF_FPOINTER;
2862 typeofv = TYPEOF_CPOINTER;
2865 typeofv = TYPEOF_GPOINTER;
2868 typeofv = TYPEOF_PPOINTER;
2871 typeofv = TYPEOF_IPOINTER;
2874 typeofv = TYPEOF_ARRAY;
2877 typeofv = TYPEOF_FUNCTION;
2883 sprintf (buffer, "%d", typeofv);
2884 tree->opval.val = constVal (buffer);
2885 tree->right = tree->left = NULL;
2886 TETYPE (tree) = getSpec (TTYPE (tree) =
2887 tree->opval.val->type);
2890 /*------------------------------------------------------------------*/
2891 /*----------------------------*/
2892 /* conditional operator '?' */
2893 /*----------------------------*/
2895 /* the type is value of the colon operator (on the right) */
2896 assert(IS_COLON_OP(tree->right));
2897 /* if already known then replace the tree : optimizer will do it
2898 but faster to do it here */
2899 if (IS_LITERAL (LTYPE(tree))) {
2900 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2901 return decorateType(tree->right->left) ;
2903 return decorateType(tree->right->right) ;
2906 tree->right = decorateType(tree->right);
2907 TTYPE (tree) = RTYPE(tree);
2908 TETYPE (tree) = getSpec (TTYPE (tree));
2913 /* if they don't match we have a problem */
2914 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2916 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2917 goto errorTreeReturn;
2920 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2921 TETYPE (tree) = getSpec (TTYPE (tree));
2925 /*------------------------------------------------------------------*/
2926 /*----------------------------*/
2927 /* assignment operators */
2928 /*----------------------------*/
2931 /* for these it must be both must be integral */
2932 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2933 !IS_ARITHMETIC (RTYPE (tree)))
2935 werror (E_OPS_INTEGRAL);
2936 goto errorTreeReturn;
2939 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2941 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2942 werror (E_CODE_WRITE, " ");
2946 werror (E_LVALUE_REQUIRED, "*= or /=");
2947 goto errorTreeReturn;
2958 /* for these it must be both must be integral */
2959 if (!IS_INTEGRAL (LTYPE (tree)) ||
2960 !IS_INTEGRAL (RTYPE (tree)))
2962 werror (E_OPS_INTEGRAL);
2963 goto errorTreeReturn;
2966 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2968 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2969 werror (E_CODE_WRITE, " ");
2973 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2974 goto errorTreeReturn;
2980 /*------------------------------------------------------------------*/
2981 /*----------------------------*/
2983 /*----------------------------*/
2985 if (!(IS_PTR (LTYPE (tree)) ||
2986 IS_ARITHMETIC (LTYPE (tree))))
2988 werror (E_PLUS_INVALID, "-=");
2989 goto errorTreeReturn;
2992 if (!(IS_PTR (RTYPE (tree)) ||
2993 IS_ARITHMETIC (RTYPE (tree))))
2995 werror (E_PLUS_INVALID, "-=");
2996 goto errorTreeReturn;
2999 TETYPE (tree) = getSpec (TTYPE (tree) =
3000 computeType (LTYPE (tree),
3003 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3004 werror (E_CODE_WRITE, " ");
3008 werror (E_LVALUE_REQUIRED, "-=");
3009 goto errorTreeReturn;
3015 /*------------------------------------------------------------------*/
3016 /*----------------------------*/
3018 /*----------------------------*/
3020 /* this is not a unary operation */
3021 /* if both pointers then problem */
3022 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3024 werror (E_PTR_PLUS_PTR);
3025 goto errorTreeReturn;
3028 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3030 werror (E_PLUS_INVALID, "+=");
3031 goto errorTreeReturn;
3034 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3036 werror (E_PLUS_INVALID, "+=");
3037 goto errorTreeReturn;
3040 TETYPE (tree) = getSpec (TTYPE (tree) =
3041 computeType (LTYPE (tree),
3044 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3045 werror (E_CODE_WRITE, " ");
3049 werror (E_LVALUE_REQUIRED, "+=");
3050 goto errorTreeReturn;
3053 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3054 tree->opval.op = '=';
3058 /*------------------------------------------------------------------*/
3059 /*----------------------------*/
3060 /* straight assignemnt */
3061 /*----------------------------*/
3063 /* cannot be an aggregate */
3064 if (IS_AGGREGATE (LTYPE (tree)))
3066 werror (E_AGGR_ASSIGN);
3067 goto errorTreeReturn;
3070 /* they should either match or be castable */
3071 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3073 werror (E_TYPE_MISMATCH, "assignment", " ");
3074 fprintf (stderr, "type --> '");
3075 printTypeChain (RTYPE (tree), stderr);
3076 fprintf (stderr, "' ");
3077 fprintf (stderr, "assigned to type --> '");
3078 printTypeChain (LTYPE (tree), stderr);
3079 fprintf (stderr, "'\n");
3080 goto errorTreeReturn;
3083 /* if the left side of the tree is of type void
3084 then report error */
3085 if (IS_VOID (LTYPE (tree)))
3087 werror (E_CAST_ZERO);
3088 printFromToType(RTYPE(tree), LTYPE(tree));
3091 TETYPE (tree) = getSpec (TTYPE (tree) =
3095 if (!tree->initMode ) {
3096 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3097 werror (E_CODE_WRITE, " ");
3101 werror (E_LVALUE_REQUIRED, "=");
3102 goto errorTreeReturn;
3107 /*------------------------------------------------------------------*/
3108 /*----------------------------*/
3109 /* comma operator */
3110 /*----------------------------*/
3112 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3115 /*------------------------------------------------------------------*/
3116 /*----------------------------*/
3118 /*----------------------------*/
3122 if (processParms (tree->left,
3123 FUNC_ARGS(tree->left->ftype),
3124 tree->right, &parmNumber, TRUE)) {
3125 goto errorTreeReturn;
3128 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3129 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3131 //FUNC_ARGS(tree->left->ftype) =
3132 //reverseVal (FUNC_ARGS(tree->left->ftype));
3133 reverseParms (tree->right);
3136 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3139 /*------------------------------------------------------------------*/
3140 /*----------------------------*/
3141 /* return statement */
3142 /*----------------------------*/
3147 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3149 werror (W_RETURN_MISMATCH);
3150 printFromToType (RTYPE(tree), currFunc->type->next);
3151 goto errorTreeReturn;
3154 if (IS_VOID (currFunc->type->next)
3156 !IS_VOID (RTYPE (tree)))
3158 werror (E_FUNC_VOID);
3159 goto errorTreeReturn;
3162 /* if there is going to be a casing required then add it */
3163 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3166 decorateType (newNode (CAST,
3167 newAst_LINK (copyLinkChain (currFunc->type->next)),
3176 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3178 werror (E_VOID_FUNC, currFunc->name);
3179 goto errorTreeReturn;
3182 TTYPE (tree) = TETYPE (tree) = NULL;
3185 /*------------------------------------------------------------------*/
3186 /*----------------------------*/
3187 /* switch statement */
3188 /*----------------------------*/
3190 /* the switch value must be an integer */
3191 if (!IS_INTEGRAL (LTYPE (tree)))
3193 werror (E_SWITCH_NON_INTEGER);
3194 goto errorTreeReturn;
3197 TTYPE (tree) = TETYPE (tree) = NULL;
3200 /*------------------------------------------------------------------*/
3201 /*----------------------------*/
3203 /*----------------------------*/
3205 tree->left = backPatchLabels (tree->left,
3208 TTYPE (tree) = TETYPE (tree) = NULL;
3211 /*------------------------------------------------------------------*/
3212 /*----------------------------*/
3214 /*----------------------------*/
3217 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3218 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3219 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3221 /* if the for loop is reversible then
3222 reverse it otherwise do what we normally
3228 if (isLoopReversible (tree, &sym, &init, &end))
3229 return reverseLoop (tree, sym, init, end);
3231 return decorateType (createFor (AST_FOR (tree, trueLabel),
3232 AST_FOR (tree, continueLabel),
3233 AST_FOR (tree, falseLabel),
3234 AST_FOR (tree, condLabel),
3235 AST_FOR (tree, initExpr),
3236 AST_FOR (tree, condExpr),
3237 AST_FOR (tree, loopExpr),
3241 TTYPE (tree) = TETYPE (tree) = NULL;
3245 /* some error found this tree will be killed */
3247 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3248 tree->opval.op = NULLOP;
3254 /*-----------------------------------------------------------------*/
3255 /* sizeofOp - processes size of operation */
3256 /*-----------------------------------------------------------------*/
3258 sizeofOp (sym_link * type)
3262 /* make sure the type is complete and sane */
3263 checkTypeSanity(type, "(sizeof)");
3265 /* get the size and convert it to character */
3266 sprintf (buff, "%d", getSize (type));
3268 /* now convert into value */
3269 return constVal (buff);
3273 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3274 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3275 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3276 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3277 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3278 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3279 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3281 /*-----------------------------------------------------------------*/
3282 /* backPatchLabels - change and or not operators to flow control */
3283 /*-----------------------------------------------------------------*/
3285 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3291 if (!(IS_ANDORNOT (tree)))
3294 /* if this an and */
3297 static int localLbl = 0;
3300 sprintf (buffer, "_and_%d", localLbl++);
3301 localLabel = newSymbol (buffer, NestLevel);
3303 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3305 /* if left is already a IFX then just change the if true label in that */
3306 if (!IS_IFX (tree->left))
3307 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3309 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3310 /* right is a IFX then just join */
3311 if (IS_IFX (tree->right))
3312 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3314 tree->right = createLabel (localLabel, tree->right);
3315 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3317 return newNode (NULLOP, tree->left, tree->right);
3320 /* if this is an or operation */
3323 static int localLbl = 0;
3326 sprintf (buffer, "_or_%d", localLbl++);
3327 localLabel = newSymbol (buffer, NestLevel);
3329 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3331 /* if left is already a IFX then just change the if true label in that */
3332 if (!IS_IFX (tree->left))
3333 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3335 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3336 /* right is a IFX then just join */
3337 if (IS_IFX (tree->right))
3338 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3340 tree->right = createLabel (localLabel, tree->right);
3341 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3343 return newNode (NULLOP, tree->left, tree->right);
3349 int wasnot = IS_NOT (tree->left);
3350 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3352 /* if the left is already a IFX */
3353 if (!IS_IFX (tree->left))
3354 tree->left = newNode (IFX, tree->left, NULL);
3358 tree->left->trueLabel = trueLabel;
3359 tree->left->falseLabel = falseLabel;
3363 tree->left->trueLabel = falseLabel;
3364 tree->left->falseLabel = trueLabel;
3371 tree->trueLabel = trueLabel;
3372 tree->falseLabel = falseLabel;
3379 /*-----------------------------------------------------------------*/
3380 /* createBlock - create expression tree for block */
3381 /*-----------------------------------------------------------------*/
3383 createBlock (symbol * decl, ast * body)
3387 /* if the block has nothing */
3391 ex = newNode (BLOCK, NULL, body);
3392 ex->values.sym = decl;
3394 ex->right = ex->right;
3400 /*-----------------------------------------------------------------*/
3401 /* createLabel - creates the expression tree for labels */
3402 /*-----------------------------------------------------------------*/
3404 createLabel (symbol * label, ast * stmnt)
3407 char name[SDCC_NAME_MAX + 1];
3410 /* must create fresh symbol if the symbol name */
3411 /* exists in the symbol table, since there can */
3412 /* be a variable with the same name as the labl */
3413 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3414 (csym->level == label->level))
3415 label = newSymbol (label->name, label->level);
3417 /* change the name before putting it in add _ */
3418 sprintf (name, "%s", label->name);
3420 /* put the label in the LabelSymbol table */
3421 /* but first check if a label of the same */
3423 if ((csym = findSym (LabelTab, NULL, name)))
3424 werror (E_DUPLICATE_LABEL, label->name);
3426 addSym (LabelTab, label, name, label->level, 0, 0);
3429 label->key = labelKey++;
3430 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3436 /*-----------------------------------------------------------------*/
3437 /* createCase - generates the parsetree for a case statement */
3438 /*-----------------------------------------------------------------*/
3440 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3442 char caseLbl[SDCC_NAME_MAX + 1];
3446 /* if the switch statement does not exist */
3447 /* then case is out of context */
3450 werror (E_CASE_CONTEXT);
3454 caseVal = decorateType (resolveSymbols (caseVal));
3455 /* if not a constant then error */
3456 if (!IS_LITERAL (caseVal->ftype))
3458 werror (E_CASE_CONSTANT);
3462 /* if not a integer than error */
3463 if (!IS_INTEGRAL (caseVal->ftype))
3465 werror (E_CASE_NON_INTEGER);
3469 /* find the end of the switch values chain */
3470 if (!(val = swStat->values.switchVals.swVals))
3471 swStat->values.switchVals.swVals = caseVal->opval.val;
3474 /* also order the cases according to value */
3476 int cVal = (int) floatFromVal (caseVal->opval.val);
3477 while (val && (int) floatFromVal (val) < cVal)
3483 /* if we reached the end then */
3486 pval->next = caseVal->opval.val;
3490 /* we found a value greater than */
3491 /* the current value we must add this */
3492 /* before the value */
3493 caseVal->opval.val->next = val;
3495 /* if this was the first in chain */
3496 if (swStat->values.switchVals.swVals == val)
3497 swStat->values.switchVals.swVals =
3500 pval->next = caseVal->opval.val;
3505 /* create the case label */
3506 sprintf (caseLbl, "_case_%d_%d",
3507 swStat->values.switchVals.swNum,
3508 (int) floatFromVal (caseVal->opval.val));
3510 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3515 /*-----------------------------------------------------------------*/
3516 /* createDefault - creates the parse tree for the default statement */
3517 /*-----------------------------------------------------------------*/
3519 createDefault (ast * swStat, ast * stmnt)
3521 char defLbl[SDCC_NAME_MAX + 1];
3523 /* if the switch statement does not exist */
3524 /* then case is out of context */
3527 werror (E_CASE_CONTEXT);
3531 /* turn on the default flag */
3532 swStat->values.switchVals.swDefault = 1;
3534 /* create the label */
3535 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3536 return createLabel (newSymbol (defLbl, 0), stmnt);
3539 /*-----------------------------------------------------------------*/
3540 /* createIf - creates the parsetree for the if statement */
3541 /*-----------------------------------------------------------------*/
3543 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3545 static int Lblnum = 0;
3547 symbol *ifTrue, *ifFalse, *ifEnd;
3549 /* if neither exists */
3550 if (!elseBody && !ifBody) {
3551 // if there are no side effects (i++, j() etc)
3552 if (!hasSEFcalls(condAst)) {
3557 /* create the labels */
3558 sprintf (buffer, "_iffalse_%d", Lblnum);
3559 ifFalse = newSymbol (buffer, NestLevel);
3560 /* if no else body then end == false */
3565 sprintf (buffer, "_ifend_%d", Lblnum);
3566 ifEnd = newSymbol (buffer, NestLevel);
3569 sprintf (buffer, "_iftrue_%d", Lblnum);
3570 ifTrue = newSymbol (buffer, NestLevel);
3574 /* attach the ifTrue label to the top of it body */
3575 ifBody = createLabel (ifTrue, ifBody);
3576 /* attach a goto end to the ifBody if else is present */
3579 ifBody = newNode (NULLOP, ifBody,
3581 newAst_VALUE (symbolVal (ifEnd)),
3583 /* put the elseLabel on the else body */
3584 elseBody = createLabel (ifFalse, elseBody);
3585 /* out the end at the end of the body */
3586 elseBody = newNode (NULLOP,
3588 createLabel (ifEnd, NULL));
3592 ifBody = newNode (NULLOP, ifBody,
3593 createLabel (ifFalse, NULL));
3595 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3596 if (IS_IFX (condAst))
3599 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3601 return newNode (NULLOP, ifTree,
3602 newNode (NULLOP, ifBody, elseBody));
3606 /*-----------------------------------------------------------------*/
3607 /* createDo - creates parse tree for do */
3610 /* _docontinue_n: */
3611 /* condition_expression +-> trueLabel -> _dobody_n */
3613 /* +-> falseLabel-> _dobreak_n */
3615 /*-----------------------------------------------------------------*/
3617 createDo (symbol * trueLabel, symbol * continueLabel,
3618 symbol * falseLabel, ast * condAst, ast * doBody)
3623 /* if the body does not exist then it is simple */
3626 condAst = backPatchLabels (condAst, continueLabel, NULL);
3627 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3628 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3629 doTree->trueLabel = continueLabel;
3630 doTree->falseLabel = NULL;
3634 /* otherwise we have a body */
3635 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3637 /* attach the body label to the top */
3638 doBody = createLabel (trueLabel, doBody);
3639 /* attach the continue label to end of body */
3640 doBody = newNode (NULLOP, doBody,
3641 createLabel (continueLabel, NULL));
3643 /* now put the break label at the end */
3644 if (IS_IFX (condAst))
3647 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3649 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3651 /* putting it together */
3652 return newNode (NULLOP, doBody, doTree);
3655 /*-----------------------------------------------------------------*/
3656 /* createFor - creates parse tree for 'for' statement */
3659 /* condExpr +-> trueLabel -> _forbody_n */
3661 /* +-> falseLabel-> _forbreak_n */
3664 /* _forcontinue_n: */
3666 /* goto _forcond_n ; */
3668 /*-----------------------------------------------------------------*/
3670 createFor (symbol * trueLabel, symbol * continueLabel,
3671 symbol * falseLabel, symbol * condLabel,
3672 ast * initExpr, ast * condExpr, ast * loopExpr,
3677 /* if loopexpression not present then we can generate it */
3678 /* the same way as a while */
3680 return newNode (NULLOP, initExpr,
3681 createWhile (trueLabel, continueLabel,
3682 falseLabel, condExpr, forBody));
3683 /* vanilla for statement */
3684 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3686 if (condExpr && !IS_IFX (condExpr))
3687 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3690 /* attach condition label to condition */
3691 condExpr = createLabel (condLabel, condExpr);
3693 /* attach body label to body */
3694 forBody = createLabel (trueLabel, forBody);
3696 /* attach continue to forLoop expression & attach */
3697 /* goto the forcond @ and of loopExpression */
3698 loopExpr = createLabel (continueLabel,
3702 newAst_VALUE (symbolVal (condLabel)),
3704 /* now start putting them together */
3705 forTree = newNode (NULLOP, initExpr, condExpr);
3706 forTree = newNode (NULLOP, forTree, forBody);
3707 forTree = newNode (NULLOP, forTree, loopExpr);
3708 /* finally add the break label */
3709 forTree = newNode (NULLOP, forTree,
3710 createLabel (falseLabel, NULL));
3714 /*-----------------------------------------------------------------*/
3715 /* createWhile - creates parse tree for while statement */
3716 /* the while statement will be created as follows */
3718 /* _while_continue_n: */
3719 /* condition_expression +-> trueLabel -> _while_boby_n */
3721 /* +-> falseLabel -> _while_break_n */
3722 /* _while_body_n: */
3724 /* goto _while_continue_n */
3725 /* _while_break_n: */
3726 /*-----------------------------------------------------------------*/
3728 createWhile (symbol * trueLabel, symbol * continueLabel,
3729 symbol * falseLabel, ast * condExpr, ast * whileBody)
3733 /* put the continue label */
3734 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3735 condExpr = createLabel (continueLabel, condExpr);
3736 condExpr->lineno = 0;
3738 /* put the body label in front of the body */
3739 whileBody = createLabel (trueLabel, whileBody);
3740 whileBody->lineno = 0;
3741 /* put a jump to continue at the end of the body */
3742 /* and put break label at the end of the body */
3743 whileBody = newNode (NULLOP,
3746 newAst_VALUE (symbolVal (continueLabel)),
3747 createLabel (falseLabel, NULL)));
3749 /* put it all together */
3750 if (IS_IFX (condExpr))
3751 whileTree = condExpr;
3754 whileTree = newNode (IFX, condExpr, NULL);
3755 /* put the true & false labels in place */
3756 whileTree->trueLabel = trueLabel;
3757 whileTree->falseLabel = falseLabel;
3760 return newNode (NULLOP, whileTree, whileBody);
3763 /*-----------------------------------------------------------------*/
3764 /* optimizeGetHbit - get highest order bit of the expression */
3765 /*-----------------------------------------------------------------*/
3767 optimizeGetHbit (ast * tree)
3770 /* if this is not a bit and */
3771 if (!IS_BITAND (tree))
3774 /* will look for tree of the form
3775 ( expr >> ((sizeof expr) -1) ) & 1 */
3776 if (!IS_AST_LIT_VALUE (tree->right))
3779 if (AST_LIT_VALUE (tree->right) != 1)
3782 if (!IS_RIGHT_OP (tree->left))
3785 if (!IS_AST_LIT_VALUE (tree->left->right))
3788 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3789 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3792 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3796 /*-----------------------------------------------------------------*/
3797 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3798 /*-----------------------------------------------------------------*/
3800 optimizeRRCRLC (ast * root)
3802 /* will look for trees of the form
3803 (?expr << 1) | (?expr >> 7) or
3804 (?expr >> 7) | (?expr << 1) will make that
3805 into a RLC : operation ..
3807 (?expr >> 1) | (?expr << 7) or
3808 (?expr << 7) | (?expr >> 1) will make that
3809 into a RRC operation
3810 note : by 7 I mean (number of bits required to hold the
3812 /* if the root operations is not a | operation the not */
3813 if (!IS_BITOR (root))
3816 /* I have to think of a better way to match patterns this sucks */
3817 /* that aside let start looking for the first case : I use a the
3818 negative check a lot to improve the efficiency */
3819 /* (?expr << 1) | (?expr >> 7) */
3820 if (IS_LEFT_OP (root->left) &&
3821 IS_RIGHT_OP (root->right))
3824 if (!SPEC_USIGN (TETYPE (root->left->left)))
3827 if (!IS_AST_LIT_VALUE (root->left->right) ||
3828 !IS_AST_LIT_VALUE (root->right->right))
3831 /* make sure it is the same expression */
3832 if (!isAstEqual (root->left->left,
3836 if (AST_LIT_VALUE (root->left->right) != 1)
3839 if (AST_LIT_VALUE (root->right->right) !=
3840 (getSize (TTYPE (root->left->left)) * 8 - 1))
3843 /* whew got the first case : create the AST */
3844 return newNode (RLC, root->left->left, NULL);
3848 /* check for second case */
3849 /* (?expr >> 7) | (?expr << 1) */
3850 if (IS_LEFT_OP (root->right) &&
3851 IS_RIGHT_OP (root->left))
3854 if (!SPEC_USIGN (TETYPE (root->left->left)))
3857 if (!IS_AST_LIT_VALUE (root->left->right) ||
3858 !IS_AST_LIT_VALUE (root->right->right))
3861 /* make sure it is the same symbol */
3862 if (!isAstEqual (root->left->left,
3866 if (AST_LIT_VALUE (root->right->right) != 1)
3869 if (AST_LIT_VALUE (root->left->right) !=
3870 (getSize (TTYPE (root->left->left)) * 8 - 1))
3873 /* whew got the first case : create the AST */
3874 return newNode (RLC, root->left->left, NULL);
3879 /* third case for RRC */
3880 /* (?symbol >> 1) | (?symbol << 7) */
3881 if (IS_LEFT_OP (root->right) &&
3882 IS_RIGHT_OP (root->left))
3885 if (!SPEC_USIGN (TETYPE (root->left->left)))
3888 if (!IS_AST_LIT_VALUE (root->left->right) ||
3889 !IS_AST_LIT_VALUE (root->right->right))
3892 /* make sure it is the same symbol */
3893 if (!isAstEqual (root->left->left,
3897 if (AST_LIT_VALUE (root->left->right) != 1)
3900 if (AST_LIT_VALUE (root->right->right) !=
3901 (getSize (TTYPE (root->left->left)) * 8 - 1))
3904 /* whew got the first case : create the AST */
3905 return newNode (RRC, root->left->left, NULL);
3909 /* fourth and last case for now */
3910 /* (?symbol << 7) | (?symbol >> 1) */
3911 if (IS_RIGHT_OP (root->right) &&
3912 IS_LEFT_OP (root->left))
3915 if (!SPEC_USIGN (TETYPE (root->left->left)))
3918 if (!IS_AST_LIT_VALUE (root->left->right) ||
3919 !IS_AST_LIT_VALUE (root->right->right))
3922 /* make sure it is the same symbol */
3923 if (!isAstEqual (root->left->left,
3927 if (AST_LIT_VALUE (root->right->right) != 1)
3930 if (AST_LIT_VALUE (root->left->right) !=
3931 (getSize (TTYPE (root->left->left)) * 8 - 1))
3934 /* whew got the first case : create the AST */
3935 return newNode (RRC, root->left->left, NULL);
3939 /* not found return root */
3943 /*-----------------------------------------------------------------*/
3944 /* optimizeCompare - otimizes compares for bit variables */
3945 /*-----------------------------------------------------------------*/
3947 optimizeCompare (ast * root)
3949 ast *optExpr = NULL;
3952 unsigned int litValue;
3954 /* if nothing then return nothing */
3958 /* if not a compare op then do leaves */
3959 if (!IS_COMPARE_OP (root))
3961 root->left = optimizeCompare (root->left);
3962 root->right = optimizeCompare (root->right);
3966 /* if left & right are the same then depending
3967 of the operation do */
3968 if (isAstEqual (root->left, root->right))
3970 switch (root->opval.op)
3975 optExpr = newAst_VALUE (constVal ("0"));
3980 optExpr = newAst_VALUE (constVal ("1"));
3984 return decorateType (optExpr);
3987 vleft = (root->left->type == EX_VALUE ?
3988 root->left->opval.val : NULL);
3990 vright = (root->right->type == EX_VALUE ?
3991 root->right->opval.val : NULL);
3993 /* if left is a BITVAR in BITSPACE */
3994 /* and right is a LITERAL then opt- */
3995 /* imize else do nothing */
3996 if (vleft && vright &&
3997 IS_BITVAR (vleft->etype) &&
3998 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3999 IS_LITERAL (vright->etype))
4002 /* if right side > 1 then comparison may never succeed */
4003 if ((litValue = (int) floatFromVal (vright)) > 1)
4005 werror (W_BAD_COMPARE);
4011 switch (root->opval.op)
4013 case '>': /* bit value greater than 1 cannot be */
4014 werror (W_BAD_COMPARE);
4018 case '<': /* bit value < 1 means 0 */
4020 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4023 case LE_OP: /* bit value <= 1 means no check */
4024 optExpr = newAst_VALUE (vright);
4027 case GE_OP: /* bit value >= 1 means only check for = */
4029 optExpr = newAst_VALUE (vleft);
4034 { /* literal is zero */
4035 switch (root->opval.op)
4037 case '<': /* bit value < 0 cannot be */
4038 werror (W_BAD_COMPARE);
4042 case '>': /* bit value > 0 means 1 */
4044 optExpr = newAst_VALUE (vleft);
4047 case LE_OP: /* bit value <= 0 means no check */
4048 case GE_OP: /* bit value >= 0 means no check */
4049 werror (W_BAD_COMPARE);
4053 case EQ_OP: /* bit == 0 means ! of bit */
4054 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4058 return decorateType (resolveSymbols (optExpr));
4059 } /* end-of-if of BITVAR */
4064 /*-----------------------------------------------------------------*/
4065 /* addSymToBlock : adds the symbol to the first block we find */
4066 /*-----------------------------------------------------------------*/
4068 addSymToBlock (symbol * sym, ast * tree)
4070 /* reached end of tree or a leaf */
4071 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4075 if (IS_AST_OP (tree) &&
4076 tree->opval.op == BLOCK)
4079 symbol *lsym = copySymbol (sym);
4081 lsym->next = AST_VALUES (tree, sym);
4082 AST_VALUES (tree, sym) = lsym;
4086 addSymToBlock (sym, tree->left);
4087 addSymToBlock (sym, tree->right);
4090 /*-----------------------------------------------------------------*/
4091 /* processRegParms - do processing for register parameters */
4092 /*-----------------------------------------------------------------*/
4094 processRegParms (value * args, ast * body)
4098 if (IS_REGPARM (args->etype))
4099 addSymToBlock (args->sym, body);
4104 /*-----------------------------------------------------------------*/
4105 /* resetParmKey - resets the operandkeys for the symbols */
4106 /*-----------------------------------------------------------------*/
4107 DEFSETFUNC (resetParmKey)
4118 /*-----------------------------------------------------------------*/
4119 /* createFunction - This is the key node that calls the iCode for */
4120 /* generating the code for a function. Note code */
4121 /* is generated function by function, later when */
4122 /* add inter-procedural analysis this will change */
4123 /*-----------------------------------------------------------------*/
4125 createFunction (symbol * name, ast * body)
4131 iCode *piCode = NULL;
4133 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4134 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4136 /* if check function return 0 then some problem */
4137 if (checkFunction (name, NULL) == 0)
4140 /* create a dummy block if none exists */
4142 body = newNode (BLOCK, NULL, NULL);
4146 /* check if the function name already in the symbol table */
4147 if ((csym = findSym (SymbolTab, NULL, name->name)))
4150 /* special case for compiler defined functions
4151 we need to add the name to the publics list : this
4152 actually means we are now compiling the compiler
4156 addSet (&publics, name);
4162 allocVariables (name);
4164 name->lastLine = yylineno;
4167 /* set the stack pointer */
4168 /* PENDING: check this for the mcs51 */
4169 stackPtr = -port->stack.direction * port->stack.call_overhead;
4170 if (IFFUNC_ISISR (name->type))
4171 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4172 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4173 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4175 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4177 fetype = getSpec (name->type); /* get the specifier for the function */
4178 /* if this is a reentrant function then */
4179 if (IFFUNC_ISREENT (name->type))
4182 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4184 /* do processing for parameters that are passed in registers */
4185 processRegParms (FUNC_ARGS(name->type), body);
4187 /* set the stack pointer */
4191 /* allocate & autoinit the block variables */
4192 processBlockVars (body, &stack, ALLOCATE);
4194 /* save the stack information */
4195 if (options.useXstack)
4196 name->xstack = SPEC_STAK (fetype) = stack;
4198 name->stack = SPEC_STAK (fetype) = stack;
4200 /* name needs to be mangled */
4201 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4203 body = resolveSymbols (body); /* resolve the symbols */
4204 body = decorateType (body); /* propagateType & do semantic checks */
4206 ex = newAst_VALUE (symbolVal (name)); /* create name */
4207 ex = newNode (FUNCTION, ex, body);
4208 ex->values.args = FUNC_ARGS(name->type);
4210 if (options.dump_tree) PA(ex);
4213 werror (E_FUNC_NO_CODE, name->name);
4217 /* create the node & generate intermediate code */
4219 codeOutFile = code->oFile;
4220 piCode = iCodeFromAst (ex);
4224 werror (E_FUNC_NO_CODE, name->name);
4228 eBBlockFromiCode (piCode);
4230 /* if there are any statics then do them */
4233 GcurMemmap = statsg;
4234 codeOutFile = statsg->oFile;
4235 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4241 /* dealloc the block variables */
4242 processBlockVars (body, &stack, DEALLOCATE);
4243 /* deallocate paramaters */
4244 deallocParms (FUNC_ARGS(name->type));
4246 if (IFFUNC_ISREENT (name->type))
4249 /* we are done freeup memory & cleanup */
4251 if (port->reset_labelKey) labelKey = 1;
4253 FUNC_HASBODY(name->type) = 1;
4254 addSet (&operKeyReset, name);
4255 applyToSet (operKeyReset, resetParmKey);
4258 cdbStructBlock (1, cdbFile);
4260 cleanUpLevel (LabelTab, 0);
4261 cleanUpBlock (StructTab, 1);
4262 cleanUpBlock (TypedefTab, 1);
4264 xstack->syms = NULL;
4265 istack->syms = NULL;
4270 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4271 /*-----------------------------------------------------------------*/
4272 /* ast_print : prints the ast (for debugging purposes) */
4273 /*-----------------------------------------------------------------*/
4275 void ast_print (ast * tree, FILE *outfile, int indent)
4280 /* can print only decorated trees */
4281 if (!tree->decorated) return;
4283 /* if any child is an error | this one is an error do nothing */
4284 if (tree->isError ||
4285 (tree->left && tree->left->isError) ||
4286 (tree->right && tree->right->isError)) {
4287 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4291 /* print the line */
4292 /* if not block & function */
4293 if (tree->type == EX_OP &&
4294 (tree->opval.op != FUNCTION &&
4295 tree->opval.op != BLOCK &&
4296 tree->opval.op != NULLOP)) {
4299 if (tree->opval.op == FUNCTION) {
4301 value *args=FUNC_ARGS(tree->left->opval.val->type);
4302 fprintf(outfile,"FUNCTION (%s=%p) type (",
4303 tree->left->opval.val->name, tree);
4304 printTypeChain (tree->ftype,outfile);
4305 fprintf(outfile,") args (");
4308 fprintf (outfile, ", ");
4310 printTypeChain (args ? args->type : NULL, outfile);
4312 args= args ? args->next : NULL;
4314 fprintf(outfile,")\n");
4315 ast_print(tree->left,outfile,indent);
4316 ast_print(tree->right,outfile,indent);
4319 if (tree->opval.op == BLOCK) {
4320 symbol *decls = tree->values.sym;
4321 INDENT(indent,outfile);
4322 fprintf(outfile,"{\n");
4324 INDENT(indent+2,outfile);
4325 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4326 decls->name, decls);
4327 printTypeChain(decls->type,outfile);
4328 fprintf(outfile,")\n");
4330 decls = decls->next;
4332 ast_print(tree->right,outfile,indent+2);
4333 INDENT(indent,outfile);
4334 fprintf(outfile,"}\n");
4337 if (tree->opval.op == NULLOP) {
4338 fprintf(outfile,"\n");
4339 ast_print(tree->left,outfile,indent);
4340 fprintf(outfile,"\n");
4341 ast_print(tree->right,outfile,indent);
4344 INDENT(indent,outfile);
4346 /*------------------------------------------------------------------*/
4347 /*----------------------------*/
4348 /* leaf has been reached */
4349 /*----------------------------*/
4350 /* if this is of type value */
4351 /* just get the type */
4352 if (tree->type == EX_VALUE) {
4354 if (IS_LITERAL (tree->opval.val->etype)) {
4355 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4356 (int) floatFromVal(tree->opval.val),
4357 (int) floatFromVal(tree->opval.val),
4358 floatFromVal(tree->opval.val));
4359 } else if (tree->opval.val->sym) {
4360 /* if the undefined flag is set then give error message */
4361 if (tree->opval.val->sym->undefined) {
4362 fprintf(outfile,"UNDEFINED SYMBOL ");
4364 fprintf(outfile,"SYMBOL ");
4366 fprintf(outfile,"(%s=%p)",
4367 tree->opval.val->sym->name,tree);
4370 fprintf(outfile," type (");
4371 printTypeChain(tree->ftype,outfile);
4372 fprintf(outfile,")\n");
4374 fprintf(outfile,"\n");
4379 /* if type link for the case of cast */
4380 if (tree->type == EX_LINK) {
4381 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4382 printTypeChain(tree->opval.lnk,outfile);
4383 fprintf(outfile,")\n");
4388 /* depending on type of operator do */
4390 switch (tree->opval.op) {
4391 /*------------------------------------------------------------------*/
4392 /*----------------------------*/
4394 /*----------------------------*/
4396 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4397 printTypeChain(tree->ftype,outfile);
4398 fprintf(outfile,")\n");
4399 ast_print(tree->left,outfile,indent+2);
4400 ast_print(tree->right,outfile,indent+2);
4403 /*------------------------------------------------------------------*/
4404 /*----------------------------*/
4406 /*----------------------------*/
4408 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4409 printTypeChain(tree->ftype,outfile);
4410 fprintf(outfile,")\n");
4411 ast_print(tree->left,outfile,indent+2);
4412 ast_print(tree->right,outfile,indent+2);
4415 /*------------------------------------------------------------------*/
4416 /*----------------------------*/
4417 /* struct/union pointer */
4418 /*----------------------------*/
4420 fprintf(outfile,"PTR_ACCESS (%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 /*----------------------------*/
4429 /* ++/-- operation */
4430 /*----------------------------*/
4431 case INC_OP: /* incerement operator unary so left only */
4432 fprintf(outfile,"INC_OP (%p) type (",tree);
4433 printTypeChain(tree->ftype,outfile);
4434 fprintf(outfile,")\n");
4435 ast_print(tree->left,outfile,indent+2);
4439 fprintf(outfile,"DEC_OP (%p) type (",tree);
4440 printTypeChain(tree->ftype,outfile);
4441 fprintf(outfile,")\n");
4442 ast_print(tree->left,outfile,indent+2);
4445 /*------------------------------------------------------------------*/
4446 /*----------------------------*/
4448 /*----------------------------*/
4451 fprintf(outfile,"& (%p) type (",tree);
4452 printTypeChain(tree->ftype,outfile);
4453 fprintf(outfile,")\n");
4454 ast_print(tree->left,outfile,indent+2);
4455 ast_print(tree->right,outfile,indent+2);
4457 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4458 printTypeChain(tree->ftype,outfile);
4459 fprintf(outfile,")\n");
4460 ast_print(tree->left,outfile,indent+2);
4461 ast_print(tree->right,outfile,indent+2);
4464 /*----------------------------*/
4466 /*----------------------------*/
4468 fprintf(outfile,"OR (%p) type (",tree);
4469 printTypeChain(tree->ftype,outfile);
4470 fprintf(outfile,")\n");
4471 ast_print(tree->left,outfile,indent+2);
4472 ast_print(tree->right,outfile,indent+2);
4474 /*------------------------------------------------------------------*/
4475 /*----------------------------*/
4477 /*----------------------------*/
4479 fprintf(outfile,"XOR (%p) type (",tree);
4480 printTypeChain(tree->ftype,outfile);
4481 fprintf(outfile,")\n");
4482 ast_print(tree->left,outfile,indent+2);
4483 ast_print(tree->right,outfile,indent+2);
4486 /*------------------------------------------------------------------*/
4487 /*----------------------------*/
4489 /*----------------------------*/
4491 fprintf(outfile,"DIV (%p) type (",tree);
4492 printTypeChain(tree->ftype,outfile);
4493 fprintf(outfile,")\n");
4494 ast_print(tree->left,outfile,indent+2);
4495 ast_print(tree->right,outfile,indent+2);
4497 /*------------------------------------------------------------------*/
4498 /*----------------------------*/
4500 /*----------------------------*/
4502 fprintf(outfile,"MOD (%p) type (",tree);
4503 printTypeChain(tree->ftype,outfile);
4504 fprintf(outfile,")\n");
4505 ast_print(tree->left,outfile,indent+2);
4506 ast_print(tree->right,outfile,indent+2);
4509 /*------------------------------------------------------------------*/
4510 /*----------------------------*/
4511 /* address dereference */
4512 /*----------------------------*/
4513 case '*': /* can be unary : if right is null then unary operation */
4515 fprintf(outfile,"DEREF (%p) type (",tree);
4516 printTypeChain(tree->ftype,outfile);
4517 fprintf(outfile,")\n");
4518 ast_print(tree->left,outfile,indent+2);
4521 /*------------------------------------------------------------------*/
4522 /*----------------------------*/
4523 /* multiplication */
4524 /*----------------------------*/
4525 fprintf(outfile,"MULT (%p) type (",tree);
4526 printTypeChain(tree->ftype,outfile);
4527 fprintf(outfile,")\n");
4528 ast_print(tree->left,outfile,indent+2);
4529 ast_print(tree->right,outfile,indent+2);
4533 /*------------------------------------------------------------------*/
4534 /*----------------------------*/
4535 /* unary '+' operator */
4536 /*----------------------------*/
4540 fprintf(outfile,"UPLUS (%p) type (",tree);
4541 printTypeChain(tree->ftype,outfile);
4542 fprintf(outfile,")\n");
4543 ast_print(tree->left,outfile,indent+2);
4545 /*------------------------------------------------------------------*/
4546 /*----------------------------*/
4548 /*----------------------------*/
4549 fprintf(outfile,"ADD (%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);
4556 /*------------------------------------------------------------------*/
4557 /*----------------------------*/
4559 /*----------------------------*/
4560 case '-': /* can be unary */
4562 fprintf(outfile,"UMINUS (%p) type (",tree);
4563 printTypeChain(tree->ftype,outfile);
4564 fprintf(outfile,")\n");
4565 ast_print(tree->left,outfile,indent+2);
4567 /*------------------------------------------------------------------*/
4568 /*----------------------------*/
4570 /*----------------------------*/
4571 fprintf(outfile,"SUB (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+2);
4575 ast_print(tree->right,outfile,indent+2);
4578 /*------------------------------------------------------------------*/
4579 /*----------------------------*/
4581 /*----------------------------*/
4583 fprintf(outfile,"COMPL (%p) type (",tree);
4584 printTypeChain(tree->ftype,outfile);
4585 fprintf(outfile,")\n");
4586 ast_print(tree->left,outfile,indent+2);
4588 /*------------------------------------------------------------------*/
4589 /*----------------------------*/
4591 /*----------------------------*/
4593 fprintf(outfile,"NOT (%p) type (",tree);
4594 printTypeChain(tree->ftype,outfile);
4595 fprintf(outfile,")\n");
4596 ast_print(tree->left,outfile,indent+2);
4598 /*------------------------------------------------------------------*/
4599 /*----------------------------*/
4601 /*----------------------------*/
4603 fprintf(outfile,"RRC (%p) type (",tree);
4604 printTypeChain(tree->ftype,outfile);
4605 fprintf(outfile,")\n");
4606 ast_print(tree->left,outfile,indent+2);
4610 fprintf(outfile,"RLC (%p) type (",tree);
4611 printTypeChain(tree->ftype,outfile);
4612 fprintf(outfile,")\n");
4613 ast_print(tree->left,outfile,indent+2);
4616 fprintf(outfile,"GETHBIT (%p) type (",tree);
4617 printTypeChain(tree->ftype,outfile);
4618 fprintf(outfile,")\n");
4619 ast_print(tree->left,outfile,indent+2);
4622 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4623 printTypeChain(tree->ftype,outfile);
4624 fprintf(outfile,")\n");
4625 ast_print(tree->left,outfile,indent+2);
4626 ast_print(tree->right,outfile,indent+2);
4629 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4630 printTypeChain(tree->ftype,outfile);
4631 fprintf(outfile,")\n");
4632 ast_print(tree->left,outfile,indent+2);
4633 ast_print(tree->right,outfile,indent+2);
4635 /*------------------------------------------------------------------*/
4636 /*----------------------------*/
4638 /*----------------------------*/
4639 case CAST: /* change the type */
4640 fprintf(outfile,"CAST (%p) from type (",tree);
4641 printTypeChain(tree->right->ftype,outfile);
4642 fprintf(outfile,") to type (");
4643 printTypeChain(tree->ftype,outfile);
4644 fprintf(outfile,")\n");
4645 ast_print(tree->right,outfile,indent+2);
4649 fprintf(outfile,"ANDAND (%p) type (",tree);
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->left,outfile,indent+2);
4653 ast_print(tree->right,outfile,indent+2);
4656 fprintf(outfile,"OROR (%p) type (",tree);
4657 printTypeChain(tree->ftype,outfile);
4658 fprintf(outfile,")\n");
4659 ast_print(tree->left,outfile,indent+2);
4660 ast_print(tree->right,outfile,indent+2);
4663 /*------------------------------------------------------------------*/
4664 /*----------------------------*/
4665 /* comparison operators */
4666 /*----------------------------*/
4668 fprintf(outfile,"GT(>) (%p) type (",tree);
4669 printTypeChain(tree->ftype,outfile);
4670 fprintf(outfile,")\n");
4671 ast_print(tree->left,outfile,indent+2);
4672 ast_print(tree->right,outfile,indent+2);
4675 fprintf(outfile,"LT(<) (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+2);
4679 ast_print(tree->right,outfile,indent+2);
4682 fprintf(outfile,"LE(<=) (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+2);
4686 ast_print(tree->right,outfile,indent+2);
4689 fprintf(outfile,"GE(>=) (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+2);
4693 ast_print(tree->right,outfile,indent+2);
4696 fprintf(outfile,"EQ(==) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+2);
4700 ast_print(tree->right,outfile,indent+2);
4703 fprintf(outfile,"NE(!=) (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+2);
4707 ast_print(tree->right,outfile,indent+2);
4708 /*------------------------------------------------------------------*/
4709 /*----------------------------*/
4711 /*----------------------------*/
4712 case SIZEOF: /* evaluate wihout code generation */
4713 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4716 /*------------------------------------------------------------------*/
4717 /*----------------------------*/
4718 /* conditional operator '?' */
4719 /*----------------------------*/
4721 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4722 printTypeChain(tree->ftype,outfile);
4723 fprintf(outfile,")\n");
4724 ast_print(tree->left,outfile,indent+2);
4725 ast_print(tree->right,outfile,indent+2);
4729 fprintf(outfile,"COLON(:) (%p) type (",tree);
4730 printTypeChain(tree->ftype,outfile);
4731 fprintf(outfile,")\n");
4732 ast_print(tree->left,outfile,indent+2);
4733 ast_print(tree->right,outfile,indent+2);
4736 /*------------------------------------------------------------------*/
4737 /*----------------------------*/
4738 /* assignment operators */
4739 /*----------------------------*/
4741 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4742 printTypeChain(tree->ftype,outfile);
4743 fprintf(outfile,")\n");
4744 ast_print(tree->left,outfile,indent+2);
4745 ast_print(tree->right,outfile,indent+2);
4748 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4749 printTypeChain(tree->ftype,outfile);
4750 fprintf(outfile,")\n");
4751 ast_print(tree->left,outfile,indent+2);
4752 ast_print(tree->right,outfile,indent+2);
4755 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4756 printTypeChain(tree->ftype,outfile);
4757 fprintf(outfile,")\n");
4758 ast_print(tree->left,outfile,indent+2);
4759 ast_print(tree->right,outfile,indent+2);
4762 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4763 printTypeChain(tree->ftype,outfile);
4764 fprintf(outfile,")\n");
4765 ast_print(tree->left,outfile,indent+2);
4766 ast_print(tree->right,outfile,indent+2);
4769 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+2);
4773 ast_print(tree->right,outfile,indent+2);
4776 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+2);
4780 ast_print(tree->right,outfile,indent+2);
4783 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4784 printTypeChain(tree->ftype,outfile);
4785 fprintf(outfile,")\n");
4786 ast_print(tree->left,outfile,indent+2);
4787 ast_print(tree->right,outfile,indent+2);
4789 /*------------------------------------------------------------------*/
4790 /*----------------------------*/
4792 /*----------------------------*/
4794 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4795 printTypeChain(tree->ftype,outfile);
4796 fprintf(outfile,")\n");
4797 ast_print(tree->left,outfile,indent+2);
4798 ast_print(tree->right,outfile,indent+2);
4800 /*------------------------------------------------------------------*/
4801 /*----------------------------*/
4803 /*----------------------------*/
4805 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4806 printTypeChain(tree->ftype,outfile);
4807 fprintf(outfile,")\n");
4808 ast_print(tree->left,outfile,indent+2);
4809 ast_print(tree->right,outfile,indent+2);
4811 /*------------------------------------------------------------------*/
4812 /*----------------------------*/
4813 /* straight assignemnt */
4814 /*----------------------------*/
4816 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4817 printTypeChain(tree->ftype,outfile);
4818 fprintf(outfile,")\n");
4819 ast_print(tree->left,outfile,indent+2);
4820 ast_print(tree->right,outfile,indent+2);
4822 /*------------------------------------------------------------------*/
4823 /*----------------------------*/
4824 /* comma operator */
4825 /*----------------------------*/
4827 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4828 printTypeChain(tree->ftype,outfile);
4829 fprintf(outfile,")\n");
4830 ast_print(tree->left,outfile,indent+2);
4831 ast_print(tree->right,outfile,indent+2);
4833 /*------------------------------------------------------------------*/
4834 /*----------------------------*/
4836 /*----------------------------*/
4839 fprintf(outfile,"CALL (%p) type (",tree);
4840 printTypeChain(tree->ftype,outfile);
4841 fprintf(outfile,")\n");
4842 ast_print(tree->left,outfile,indent+2);
4843 ast_print(tree->right,outfile,indent+2);
4846 fprintf(outfile,"PARMS\n");
4847 ast_print(tree->left,outfile,indent+2);
4848 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4849 ast_print(tree->right,outfile,indent+2);
4852 /*------------------------------------------------------------------*/
4853 /*----------------------------*/
4854 /* return statement */
4855 /*----------------------------*/
4857 fprintf(outfile,"RETURN (%p) type (",tree);
4858 printTypeChain(tree->right->ftype,outfile);
4859 fprintf(outfile,")\n");
4860 ast_print(tree->right,outfile,indent+2);
4862 /*------------------------------------------------------------------*/
4863 /*----------------------------*/
4864 /* label statement */
4865 /*----------------------------*/
4867 fprintf(outfile,"LABEL (%p)\n",tree);
4868 ast_print(tree->left,outfile,indent+2);
4869 ast_print(tree->right,outfile,indent);
4871 /*------------------------------------------------------------------*/
4872 /*----------------------------*/
4873 /* switch statement */
4874 /*----------------------------*/
4878 fprintf(outfile,"SWITCH (%p) ",tree);
4879 ast_print(tree->left,outfile,0);
4880 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4881 INDENT(indent+2,outfile);
4882 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4883 (int) floatFromVal(val),
4884 tree->values.switchVals.swNum,
4885 (int) floatFromVal(val));
4887 ast_print(tree->right,outfile,indent);
4890 /*------------------------------------------------------------------*/
4891 /*----------------------------*/
4893 /*----------------------------*/
4895 fprintf(outfile,"IF (%p) \n",tree);
4896 ast_print(tree->left,outfile,indent+2);
4897 if (tree->trueLabel) {
4898 INDENT(indent,outfile);
4899 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4901 if (tree->falseLabel) {
4902 INDENT(indent,outfile);
4903 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4905 ast_print(tree->right,outfile,indent+2);
4907 /*------------------------------------------------------------------*/
4908 /*----------------------------*/
4910 /*----------------------------*/
4912 fprintf(outfile,"FOR (%p) \n",tree);
4913 if (AST_FOR( tree, initExpr)) {
4914 INDENT(indent+2,outfile);
4915 fprintf(outfile,"INIT EXPR ");
4916 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4918 if (AST_FOR( tree, condExpr)) {
4919 INDENT(indent+2,outfile);
4920 fprintf(outfile,"COND EXPR ");
4921 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4923 if (AST_FOR( tree, loopExpr)) {
4924 INDENT(indent+2,outfile);
4925 fprintf(outfile,"LOOP EXPR ");
4926 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4928 fprintf(outfile,"FOR LOOP BODY \n");
4929 ast_print(tree->left,outfile,indent+2);
4938 ast_print(t,stdout,0);