1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
73 newAst_ (unsigned type)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
90 newAst_VALUE (value * val)
92 ast *ex = newAst_ (EX_VALUE);
98 newAst_OP (unsigned op)
100 ast *ex = newAst_ (EX_OP);
106 newAst_LINK (sym_link * val)
108 ast *ex = newAst_ (EX_LINK);
114 newAst_STMNT (unsigned val)
116 ast *ex = newAst_ (EX_STMNT);
117 ex->opval.stmnt = val;
121 /*-----------------------------------------------------------------*/
122 /* newNode - creates a new node */
123 /*-----------------------------------------------------------------*/
125 newNode (long op, ast * left, ast * right)
136 /*-----------------------------------------------------------------*/
137 /* newIfxNode - creates a new Ifx Node */
138 /*-----------------------------------------------------------------*/
140 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
144 /* if this is a literal then we already know the result */
145 if (condAst->etype && IS_LITERAL (condAst->etype))
147 /* then depending on the expression value */
148 if (floatFromVal (condAst->opval.val))
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (trueLabel)),
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (falseLabel)),
159 ifxNode = newNode (IFX, condAst, NULL);
160 ifxNode->trueLabel = trueLabel;
161 ifxNode->falseLabel = falseLabel;
167 /*-----------------------------------------------------------------*/
168 /* copyAstValues - copies value portion of ast if needed */
169 /*-----------------------------------------------------------------*/
171 copyAstValues (ast * dest, ast * src)
173 switch (src->opval.op)
176 dest->values.sym = copySymbolChain (src->values.sym);
180 dest->values.switchVals.swVals =
181 copyValue (src->values.switchVals.swVals);
182 dest->values.switchVals.swDefault =
183 src->values.switchVals.swDefault;
184 dest->values.switchVals.swNum =
185 src->values.switchVals.swNum;
189 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
190 strcpy (dest->values.inlineasm, src->values.inlineasm);
194 dest->values.constlist = copyLiteralList(src->values.constlist);
198 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
199 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
200 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
201 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
202 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
203 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
204 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
209 /*-----------------------------------------------------------------*/
210 /* copyAst - makes a copy of a given astession */
211 /*-----------------------------------------------------------------*/
220 dest = Safe_alloc ( sizeof (ast));
222 dest->type = src->type;
223 dest->lineno = src->lineno;
224 dest->level = src->level;
225 dest->funcName = src->funcName;
228 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
230 /* if this is a leaf */
232 if (src->type == EX_VALUE)
234 dest->opval.val = copyValue (src->opval.val);
239 if (src->type == EX_LINK)
241 dest->opval.lnk = copyLinkChain (src->opval.lnk);
245 dest->opval.op = src->opval.op;
247 /* if this is a node that has special values */
248 copyAstValues (dest, src);
250 dest->trueLabel = copySymbol (src->trueLabel);
251 dest->falseLabel = copySymbol (src->falseLabel);
252 dest->left = copyAst (src->left);
253 dest->right = copyAst (src->right);
259 /*-----------------------------------------------------------------*/
260 /* hasSEFcalls - returns TRUE if tree has a function call */
261 /*-----------------------------------------------------------------*/
263 hasSEFcalls (ast * tree)
268 if (tree->type == EX_OP &&
269 (tree->opval.op == CALL ||
270 tree->opval.op == PCALL ||
271 tree->opval.op == '=' ||
272 tree->opval.op == INC_OP ||
273 tree->opval.op == DEC_OP))
276 return (hasSEFcalls (tree->left) |
277 hasSEFcalls (tree->right));
280 /*-----------------------------------------------------------------*/
281 /* isAstEqual - compares two asts & returns 1 if they are equal */
282 /*-----------------------------------------------------------------*/
284 isAstEqual (ast * t1, ast * t2)
293 if (t1->type != t2->type)
299 if (t1->opval.op != t2->opval.op)
301 return (isAstEqual (t1->left, t2->left) &&
302 isAstEqual (t1->right, t2->right));
306 if (t1->opval.val->sym)
308 if (!t2->opval.val->sym)
311 return isSymbolEqual (t1->opval.val->sym,
316 if (t2->opval.val->sym)
319 return (floatFromVal (t1->opval.val) ==
320 floatFromVal (t2->opval.val));
324 /* only compare these two types */
332 /*-----------------------------------------------------------------*/
333 /* resolveSymbols - resolve symbols from the symbol table */
334 /*-----------------------------------------------------------------*/
336 resolveSymbols (ast * tree)
338 /* walk the entire tree and check for values */
339 /* with symbols if we find one then replace */
340 /* symbol with that from the symbol table */
346 /* if not block & function */
347 if (tree->type == EX_OP &&
348 (tree->opval.op != FUNCTION &&
349 tree->opval.op != BLOCK &&
350 tree->opval.op != NULLOP))
352 filename = tree->filename;
353 lineno = tree->lineno;
356 /* make sure we resolve the true & false labels for ifx */
357 if (tree->type == EX_OP && tree->opval.op == IFX)
363 if ((csym = findSym (LabelTab, tree->trueLabel,
364 tree->trueLabel->name)))
365 tree->trueLabel = csym;
367 werror (E_LABEL_UNDEF, tree->trueLabel->name);
370 if (tree->falseLabel)
372 if ((csym = findSym (LabelTab,
374 tree->falseLabel->name)))
375 tree->falseLabel = csym;
377 werror (E_LABEL_UNDEF, tree->falseLabel->name);
382 /* if this is a label resolve it from the labelTab */
383 if (IS_AST_VALUE (tree) &&
384 tree->opval.val->sym &&
385 tree->opval.val->sym->islbl)
388 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
389 tree->opval.val->sym->name);
392 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
394 tree->opval.val->sym = csym;
396 goto resolveChildren;
399 /* do only for leafs */
400 if (IS_AST_VALUE (tree) &&
401 tree->opval.val->sym &&
402 !tree->opval.val->sym->implicit)
405 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
407 /* if found in the symbol table & they r not the same */
408 if (csym && tree->opval.val->sym != csym)
410 tree->opval.val->sym = csym;
411 tree->opval.val->type = csym->type;
412 tree->opval.val->etype = csym->etype;
415 /* if not found in the symbol table */
416 /* mark it as undefined assume it is */
417 /* an integer in data space */
418 if (!csym && !tree->opval.val->sym->implicit)
421 /* if this is a function name then */
422 /* mark it as returning an int */
425 tree->opval.val->sym->type = newLink ();
426 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
427 tree->opval.val->sym->type->next =
428 tree->opval.val->sym->etype = newIntLink ();
429 tree->opval.val->etype = tree->opval.val->etype;
430 tree->opval.val->type = tree->opval.val->sym->type;
431 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
432 allocVariables (tree->opval.val->sym);
436 tree->opval.val->sym->undefined = 1;
437 tree->opval.val->type =
438 tree->opval.val->etype = newIntLink ();
439 tree->opval.val->sym->type =
440 tree->opval.val->sym->etype = newIntLink ();
446 resolveSymbols (tree->left);
447 resolveSymbols (tree->right);
452 /*-----------------------------------------------------------------*/
453 /* setAstLineno - walks a ast tree & sets the line number */
454 /*-----------------------------------------------------------------*/
456 setAstLineno (ast * tree, int lineno)
461 tree->lineno = lineno;
462 setAstLineno (tree->left, lineno);
463 setAstLineno (tree->right, lineno);
467 /*-----------------------------------------------------------------*/
468 /* funcOfType :- function of type with name */
469 /*-----------------------------------------------------------------*/
471 funcOfType (char *name, sym_link * type, sym_link * argType,
475 /* create the symbol */
476 sym = newSymbol (name, 0);
478 /* setup return value */
479 sym->type = newLink ();
480 DCL_TYPE (sym->type) = FUNCTION;
481 sym->type->next = copyLinkChain (type);
482 sym->etype = getSpec (sym->type);
483 FUNC_ISREENT(sym->type) = rent;
485 /* if arguments required */
489 args = FUNC_ARGS(sym->type) = newValue ();
493 args->type = copyLinkChain (argType);
494 args->etype = getSpec (args->type);
495 SPEC_EXTR(args->etype)=1;
498 args = args->next = newValue ();
505 allocVariables (sym);
510 /*-----------------------------------------------------------------*/
511 /* funcOfTypeVarg :- function of type with name and argtype */
512 /*-----------------------------------------------------------------*/
514 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
519 /* create the symbol */
520 sym = newSymbol (name, 0);
522 /* setup return value */
523 sym->type = newLink ();
524 DCL_TYPE (sym->type) = FUNCTION;
525 sym->type->next = typeFromStr(rtype);
526 sym->etype = getSpec (sym->type);
528 /* if arguments required */
531 args = FUNC_ARGS(sym->type) = newValue ();
533 for ( i = 0 ; i < nArgs ; i++ ) {
534 args->type = typeFromStr(atypes[i]);
535 args->etype = getSpec (args->type);
536 SPEC_EXTR(args->etype)=1;
537 if ((i + 1) == nArgs) break;
538 args = args->next = newValue ();
545 allocVariables (sym);
550 /*-----------------------------------------------------------------*/
551 /* reverseParms - will reverse a parameter tree */
552 /*-----------------------------------------------------------------*/
554 reverseParms (ast * ptree)
560 /* top down if we find a nonParm tree then quit */
561 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
564 ptree->left = ptree->right;
565 ptree->right = ttree;
566 reverseParms (ptree->left);
567 reverseParms (ptree->right);
573 /*-----------------------------------------------------------------*/
574 /* processParms - makes sure the parameters are okay and do some */
575 /* processing with them */
576 /*-----------------------------------------------------------------*/
578 processParms (ast * func,
581 int *parmNumber, // unused, although updated
584 /* if none of them exist */
585 if (!defParm && !actParm)
589 if (getenv("DEBUG_SANITY")) {
590 fprintf (stderr, "processParms: %s ", defParm->name);
592 /* make sure the type is complete and sane */
593 checkTypeSanity(defParm->etype, defParm->name);
596 /* if the function is being called via a pointer & */
597 /* it has not been defined a reentrant then we cannot */
598 /* have parameters */
599 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
601 werror (W_NONRENT_ARGS);
605 /* if defined parameters ended but actual parameters */
606 /* exist and this is not defined as a variable arg */
607 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
609 werror (E_TOO_MANY_PARMS);
613 /* if defined parameters present but no actual parameters */
614 if (defParm && !actParm)
616 werror (E_TOO_FEW_PARMS);
620 if (IS_VOID(actParm->ftype)) {
621 werror (E_VOID_VALUE_USED);
625 /* If this is a varargs function... */
626 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
631 if (IS_CAST_OP (actParm)
632 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
634 /* Parameter was explicitly typecast; don't touch it. */
638 ftype = actParm->ftype;
640 /* If it's a small integer, upcast to int. */
641 if (IS_INTEGRAL (ftype)
642 && (getSize (ftype) < (unsigned) INTSIZE))
644 newType = newAst_LINK(INTTYPE);
647 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
649 newType = newAst_LINK (copyLinkChain(ftype));
650 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
653 if (IS_AGGREGATE (ftype))
655 newType = newAst_LINK (copyLinkChain (ftype));
656 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
660 /* cast required; change this op to a cast. */
661 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
663 actParm->type = EX_OP;
664 actParm->opval.op = CAST;
665 actParm->left = newType;
666 actParm->right = parmCopy;
667 decorateType (actParm);
669 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
671 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
672 processParms (func, NULL, actParm->right, parmNumber, rightmost));
677 /* if defined parameters ended but actual has not & */
679 if (!defParm && actParm &&
680 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
683 resolveSymbols (actParm);
684 /* if this is a PARAM node then match left & right */
685 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
687 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
688 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
692 /* If we have found a value node by following only right-hand links,
693 * then we know that there are no more values after us.
695 * Therefore, if there are more defined parameters, the caller didn't
698 if (rightmost && defParm->next)
700 werror (E_TOO_FEW_PARMS);
705 /* the parameter type must be at least castable */
706 if (compareType (defParm->type, actParm->ftype) == 0) {
707 werror (E_INCOMPAT_TYPES);
708 printFromToType (actParm->ftype, defParm->type);
712 /* if the parameter is castable then add the cast */
713 if (compareType (defParm->type, actParm->ftype) < 0)
715 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
717 /* now change the current one to a cast */
718 actParm->type = EX_OP;
719 actParm->opval.op = CAST;
720 actParm->left = newAst_LINK (defParm->type);
721 actParm->right = pTree;
722 actParm->etype = defParm->etype;
723 actParm->ftype = defParm->type;
724 actParm->decorated=0; /* force typechecking */
725 decorateType (actParm);
728 /* make a copy and change the regparm type to the defined parm */
729 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
730 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
734 /*-----------------------------------------------------------------*/
735 /* createIvalType - generates ival for basic types */
736 /*-----------------------------------------------------------------*/
738 createIvalType (ast * sym, sym_link * type, initList * ilist)
742 /* if initList is deep */
743 if (ilist->type == INIT_DEEP)
744 ilist = ilist->init.deep;
746 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
747 return decorateType (newNode ('=', sym, iExpr));
750 /*-----------------------------------------------------------------*/
751 /* createIvalStruct - generates initial value for structures */
752 /*-----------------------------------------------------------------*/
754 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
761 sflds = SPEC_STRUCT (type)->fields;
762 if (ilist->type != INIT_DEEP)
764 werror (E_INIT_STRUCT, "");
768 iloop = ilist->init.deep;
770 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
772 /* if we have come to end */
776 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
777 lAst = decorateType (resolveSymbols (lAst));
778 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
782 werror (W_EXCESS_INITIALIZERS, "struct",
783 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
790 /*-----------------------------------------------------------------*/
791 /* createIvalArray - generates code for array initialization */
792 /*-----------------------------------------------------------------*/
794 createIvalArray (ast * sym, sym_link * type, initList * ilist)
798 int lcnt = 0, size = 0;
799 literalList *literalL;
801 /* take care of the special case */
802 /* array of characters can be init */
804 if (IS_CHAR (type->next))
805 if ((rast = createIvalCharPtr (sym,
807 decorateType (resolveSymbols (list2expr (ilist))))))
809 return decorateType (resolveSymbols (rast));
811 /* not the special case */
812 if (ilist->type != INIT_DEEP)
814 werror (E_INIT_STRUCT, "");
818 iloop = ilist->init.deep;
819 lcnt = DCL_ELEM (type);
821 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
825 aSym = decorateType (resolveSymbols(sym));
827 rast = newNode(ARRAYINIT, aSym, NULL);
828 rast->values.constlist = literalL;
830 // Make sure size is set to length of initializer list.
837 if (lcnt && size > lcnt)
839 // Array size was specified, and we have more initializers than needed.
840 char *name=sym->opval.val->sym->name;
841 int lineno=sym->opval.val->sym->lineDef;
843 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
852 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
853 aSym = decorateType (resolveSymbols (aSym));
854 rast = createIval (aSym, type->next, iloop, rast);
855 iloop = (iloop ? iloop->next : NULL);
861 /* no of elements given and we */
862 /* have generated for all of them */
865 // there has to be a better way
866 char *name=sym->opval.val->sym->name;
867 int lineno=sym->opval.val->sym->lineDef;
868 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
875 /* if we have not been given a size */
876 if (!DCL_ELEM (type))
878 DCL_ELEM (type) = size;
881 return decorateType (resolveSymbols (rast));
885 /*-----------------------------------------------------------------*/
886 /* createIvalCharPtr - generates initial values for char pointers */
887 /*-----------------------------------------------------------------*/
889 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
893 /* if this is a pointer & right is a literal array then */
894 /* just assignment will do */
895 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
896 SPEC_SCLS (iexpr->etype) == S_CODE)
897 && IS_ARRAY (iexpr->ftype)))
898 return newNode ('=', sym, iexpr);
900 /* left side is an array so we have to assign each */
902 if ((IS_LITERAL (iexpr->etype) ||
903 SPEC_SCLS (iexpr->etype) == S_CODE)
904 && IS_ARRAY (iexpr->ftype))
906 /* for each character generate an assignment */
907 /* to the array element */
908 char *s = SPEC_CVAL (iexpr->etype).v_char;
913 rast = newNode (NULLOP,
917 newAst_VALUE (valueFromLit ((float) i))),
918 newAst_VALUE (valueFromLit (*s))));
922 rast = newNode (NULLOP,
926 newAst_VALUE (valueFromLit ((float) i))),
927 newAst_VALUE (valueFromLit (*s))));
928 return decorateType (resolveSymbols (rast));
934 /*-----------------------------------------------------------------*/
935 /* createIvalPtr - generates initial value for pointers */
936 /*-----------------------------------------------------------------*/
938 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
944 if (ilist->type == INIT_DEEP)
945 ilist = ilist->init.deep;
947 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
949 /* if character pointer */
950 if (IS_CHAR (type->next))
951 if ((rast = createIvalCharPtr (sym, type, iexpr)))
954 return newNode ('=', sym, iexpr);
957 /*-----------------------------------------------------------------*/
958 /* createIval - generates code for initial value */
959 /*-----------------------------------------------------------------*/
961 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
968 /* if structure then */
969 if (IS_STRUCT (type))
970 rast = createIvalStruct (sym, type, ilist);
972 /* if this is a pointer */
974 rast = createIvalPtr (sym, type, ilist);
976 /* if this is an array */
978 rast = createIvalArray (sym, type, ilist);
980 /* if type is SPECIFIER */
982 rast = createIvalType (sym, type, ilist);
985 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
987 return decorateType (resolveSymbols (rast));
990 /*-----------------------------------------------------------------*/
991 /* initAggregates - initialises aggregate variables with initv */
992 /*-----------------------------------------------------------------*/
993 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
994 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
997 /*-----------------------------------------------------------------*/
998 /* gatherAutoInit - creates assignment expressions for initial */
1000 /*-----------------------------------------------------------------*/
1002 gatherAutoInit (symbol * autoChain)
1009 for (sym = autoChain; sym; sym = sym->next)
1012 /* resolve the symbols in the ival */
1014 resolveIvalSym (sym->ival);
1016 /* if this is a static variable & has an */
1017 /* initial value the code needs to be lifted */
1018 /* here to the main portion since they can be */
1019 /* initialised only once at the start */
1020 if (IS_STATIC (sym->etype) && sym->ival &&
1021 SPEC_SCLS (sym->etype) != S_CODE)
1025 /* insert the symbol into the symbol table */
1026 /* with level = 0 & name = rname */
1027 newSym = copySymbol (sym);
1028 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1030 /* now lift the code to main */
1031 if (IS_AGGREGATE (sym->type)) {
1032 work = initAggregates (sym, sym->ival, NULL);
1034 if (getNelements(sym->type, sym->ival)>1) {
1035 werror (W_EXCESS_INITIALIZERS, "scalar",
1036 sym->name, sym->lineDef);
1038 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1039 list2expr (sym->ival));
1042 setAstLineno (work, sym->lineDef);
1046 staticAutos = newNode (NULLOP, staticAutos, work);
1053 /* if there is an initial value */
1054 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1056 if (IS_AGGREGATE (sym->type)) {
1057 work = initAggregates (sym, sym->ival, NULL);
1059 if (getNelements(sym->type, sym->ival)>1) {
1060 werror (W_EXCESS_INITIALIZERS, "scalar",
1061 sym->name, sym->lineDef);
1063 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1064 list2expr (sym->ival));
1067 setAstLineno (work, sym->lineDef);
1070 init = newNode (NULLOP, init, work);
1079 /*-----------------------------------------------------------------*/
1080 /* stringToSymbol - creates a symbol from a literal string */
1081 /*-----------------------------------------------------------------*/
1083 stringToSymbol (value * val)
1085 char name[SDCC_NAME_MAX + 1];
1086 static int charLbl = 0;
1089 sprintf (name, "_str_%d", charLbl++);
1090 sym = newSymbol (name, 0); /* make it @ level 0 */
1091 strcpy (sym->rname, name);
1093 /* copy the type from the value passed */
1094 sym->type = copyLinkChain (val->type);
1095 sym->etype = getSpec (sym->type);
1096 /* change to storage class & output class */
1097 SPEC_SCLS (sym->etype) = S_CODE;
1098 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1099 SPEC_STAT (sym->etype) = 1;
1100 /* make the level & block = 0 */
1101 sym->block = sym->level = 0;
1103 /* create an ival */
1104 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1109 allocVariables (sym);
1112 return symbolVal (sym);
1116 /*-----------------------------------------------------------------*/
1117 /* processBlockVars - will go thru the ast looking for block if */
1118 /* a block is found then will allocate the syms */
1119 /* will also gather the auto inits present */
1120 /*-----------------------------------------------------------------*/
1122 processBlockVars (ast * tree, int *stack, int action)
1127 /* if this is a block */
1128 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1132 if (action == ALLOCATE)
1134 *stack += allocVariables (tree->values.sym);
1135 autoInit = gatherAutoInit (tree->values.sym);
1137 /* if there are auto inits then do them */
1139 tree->left = newNode (NULLOP, autoInit, tree->left);
1141 else /* action is deallocate */
1142 deallocLocal (tree->values.sym);
1145 processBlockVars (tree->left, stack, action);
1146 processBlockVars (tree->right, stack, action);
1150 /*-------------------------------------------------------------*/
1151 /* constExprTree - returns TRUE if this tree is a constant */
1153 /*-------------------------------------------------------------*/
1154 bool constExprTree (ast *cexpr) {
1160 cexpr = decorateType (resolveSymbols (cexpr));
1162 switch (cexpr->type)
1165 if (IS_AST_LIT_VALUE(cexpr)) {
1166 // this is a literal
1169 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1170 // a function's address will never change
1173 if (IS_AST_SYM_VALUE(cexpr) &&
1174 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1175 // a symbol in code space will never change
1176 // This is only for the 'char *s="hallo"' case and will have to leave
1181 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1182 "unexpected link in expression tree\n");
1185 if (cexpr->opval.op==ARRAYINIT) {
1186 fprintf (stderr, "skipping arrayinit\n");
1187 // this is a list of literals
1190 if (cexpr->opval.op=='=') {
1191 return constExprTree(cexpr->right);
1193 if (cexpr->opval.op==CAST) {
1194 // jwk: cast ignored, maybe we should throw a warning here
1195 return constExprTree(cexpr->right);
1197 if (cexpr->opval.op=='&') {
1200 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1203 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1210 /*-----------------------------------------------------------------*/
1211 /* constExprValue - returns the value of a constant expression */
1212 /* or NULL if it is not a constant expression */
1213 /*-----------------------------------------------------------------*/
1215 constExprValue (ast * cexpr, int check)
1217 cexpr = decorateType (resolveSymbols (cexpr));
1219 /* if this is not a constant then */
1220 if (!IS_LITERAL (cexpr->ftype))
1222 /* then check if this is a literal array
1224 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1225 SPEC_CVAL (cexpr->etype).v_char &&
1226 IS_ARRAY (cexpr->ftype))
1228 value *val = valFromType (cexpr->ftype);
1229 SPEC_SCLS (val->etype) = S_LITERAL;
1230 val->sym = cexpr->opval.val->sym;
1231 val->sym->type = copyLinkChain (cexpr->ftype);
1232 val->sym->etype = getSpec (val->sym->type);
1233 strcpy (val->name, cexpr->opval.val->sym->rname);
1237 /* if we are casting a literal value then */
1238 if (IS_AST_OP (cexpr) &&
1239 cexpr->opval.op == CAST &&
1240 IS_LITERAL (cexpr->left->ftype))
1241 return valCastLiteral (cexpr->ftype,
1242 floatFromVal (cexpr->left->opval.val));
1244 if (IS_AST_VALUE (cexpr))
1245 return cexpr->opval.val;
1248 werror (E_CONST_EXPECTED, "found expression");
1253 /* return the value */
1254 return cexpr->opval.val;
1258 /*-----------------------------------------------------------------*/
1259 /* isLabelInAst - will return true if a given label is found */
1260 /*-----------------------------------------------------------------*/
1262 isLabelInAst (symbol * label, ast * tree)
1264 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1267 if (IS_AST_OP (tree) &&
1268 tree->opval.op == LABEL &&
1269 isSymbolEqual (AST_SYMBOL (tree->left), label))
1272 return isLabelInAst (label, tree->right) &&
1273 isLabelInAst (label, tree->left);
1277 /*-----------------------------------------------------------------*/
1278 /* isLoopCountable - return true if the loop count can be determi- */
1279 /* -ned at compile time . */
1280 /*-----------------------------------------------------------------*/
1282 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1283 symbol ** sym, ast ** init, ast ** end)
1286 /* the loop is considered countable if the following
1287 conditions are true :-
1289 a) initExpr :- <sym> = <const>
1290 b) condExpr :- <sym> < <const1>
1291 c) loopExpr :- <sym> ++
1294 /* first check the initExpr */
1295 if (IS_AST_OP (initExpr) &&
1296 initExpr->opval.op == '=' && /* is assignment */
1297 IS_AST_SYM_VALUE (initExpr->left))
1298 { /* left is a symbol */
1300 *sym = AST_SYMBOL (initExpr->left);
1301 *init = initExpr->right;
1306 /* for now the symbol has to be of
1308 if (!IS_INTEGRAL ((*sym)->type))
1311 /* now check condExpr */
1312 if (IS_AST_OP (condExpr))
1315 switch (condExpr->opval.op)
1318 if (IS_AST_SYM_VALUE (condExpr->left) &&
1319 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1320 IS_AST_LIT_VALUE (condExpr->right))
1322 *end = condExpr->right;
1328 if (IS_AST_OP (condExpr->left) &&
1329 condExpr->left->opval.op == '>' &&
1330 IS_AST_LIT_VALUE (condExpr->left->right) &&
1331 IS_AST_SYM_VALUE (condExpr->left->left) &&
1332 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1335 *end = newNode ('+', condExpr->left->right,
1336 newAst_VALUE (constVal ("1")));
1347 /* check loop expression is of the form <sym>++ */
1348 if (!IS_AST_OP (loopExpr))
1351 /* check if <sym> ++ */
1352 if (loopExpr->opval.op == INC_OP)
1358 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1359 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1366 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1367 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1375 if (loopExpr->opval.op == ADD_ASSIGN)
1378 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1379 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1380 IS_AST_LIT_VALUE (loopExpr->right) &&
1381 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1389 /*-----------------------------------------------------------------*/
1390 /* astHasVolatile - returns true if ast contains any volatile */
1391 /*-----------------------------------------------------------------*/
1393 astHasVolatile (ast * tree)
1398 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1401 if (IS_AST_OP (tree))
1402 return astHasVolatile (tree->left) ||
1403 astHasVolatile (tree->right);
1408 /*-----------------------------------------------------------------*/
1409 /* astHasPointer - return true if the ast contains any ptr variable */
1410 /*-----------------------------------------------------------------*/
1412 astHasPointer (ast * tree)
1417 if (IS_AST_LINK (tree))
1420 /* if we hit an array expression then check
1421 only the left side */
1422 if (IS_AST_OP (tree) && tree->opval.op == '[')
1423 return astHasPointer (tree->left);
1425 if (IS_AST_VALUE (tree))
1426 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1428 return astHasPointer (tree->left) ||
1429 astHasPointer (tree->right);
1433 /*-----------------------------------------------------------------*/
1434 /* astHasSymbol - return true if the ast has the given symbol */
1435 /*-----------------------------------------------------------------*/
1437 astHasSymbol (ast * tree, symbol * sym)
1439 if (!tree || IS_AST_LINK (tree))
1442 if (IS_AST_VALUE (tree))
1444 if (IS_AST_SYM_VALUE (tree))
1445 return isSymbolEqual (AST_SYMBOL (tree), sym);
1450 return astHasSymbol (tree->left, sym) ||
1451 astHasSymbol (tree->right, sym);
1454 /*-----------------------------------------------------------------*/
1455 /* astHasDeref - return true if the ast has an indirect access */
1456 /*-----------------------------------------------------------------*/
1458 astHasDeref (ast * tree)
1460 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1463 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1465 return astHasDeref (tree->left) || astHasDeref (tree->right);
1468 /*-----------------------------------------------------------------*/
1469 /* isConformingBody - the loop body has to conform to a set of rules */
1470 /* for the loop to be considered reversible read on for rules */
1471 /*-----------------------------------------------------------------*/
1473 isConformingBody (ast * pbody, symbol * sym, ast * body)
1476 /* we are going to do a pre-order traversal of the
1477 tree && check for the following conditions. (essentially
1478 a set of very shallow tests )
1479 a) the sym passed does not participate in
1480 any arithmetic operation
1481 b) There are no function calls
1482 c) all jumps are within the body
1483 d) address of loop control variable not taken
1484 e) if an assignment has a pointer on the
1485 left hand side make sure right does not have
1486 loop control variable */
1488 /* if we reach the end or a leaf then true */
1489 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1493 /* if anything else is "volatile" */
1494 if (IS_VOLATILE (TETYPE (pbody)))
1497 /* we will walk the body in a pre-order traversal for
1499 switch (pbody->opval.op)
1501 /*------------------------------------------------------------------*/
1503 return isConformingBody (pbody->right, sym, body);
1505 /*------------------------------------------------------------------*/
1510 /*------------------------------------------------------------------*/
1511 case INC_OP: /* incerement operator unary so left only */
1514 /* sure we are not sym is not modified */
1516 IS_AST_SYM_VALUE (pbody->left) &&
1517 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1521 IS_AST_SYM_VALUE (pbody->right) &&
1522 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1527 /*------------------------------------------------------------------*/
1529 case '*': /* can be unary : if right is null then unary operation */
1534 /* if right is NULL then unary operation */
1535 /*------------------------------------------------------------------*/
1536 /*----------------------------*/
1538 /*----------------------------*/
1541 if (IS_AST_SYM_VALUE (pbody->left) &&
1542 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1545 return isConformingBody (pbody->left, sym, body);
1549 if (astHasSymbol (pbody->left, sym) ||
1550 astHasSymbol (pbody->right, sym))
1555 /*------------------------------------------------------------------*/
1563 if (IS_AST_SYM_VALUE (pbody->left) &&
1564 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1567 if (IS_AST_SYM_VALUE (pbody->right) &&
1568 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1571 return isConformingBody (pbody->left, sym, body) &&
1572 isConformingBody (pbody->right, sym, body);
1579 if (IS_AST_SYM_VALUE (pbody->left) &&
1580 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1582 return isConformingBody (pbody->left, sym, body);
1584 /*------------------------------------------------------------------*/
1596 case SIZEOF: /* evaluate wihout code generation */
1598 return isConformingBody (pbody->left, sym, body) &&
1599 isConformingBody (pbody->right, sym, body);
1601 /*------------------------------------------------------------------*/
1604 /* if left has a pointer & right has loop
1605 control variable then we cannot */
1606 if (astHasPointer (pbody->left) &&
1607 astHasSymbol (pbody->right, sym))
1609 if (astHasVolatile (pbody->left))
1612 if (IS_AST_SYM_VALUE (pbody->left) &&
1613 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1616 if (astHasVolatile (pbody->left))
1619 if (astHasDeref(pbody->right)) return FALSE;
1621 return isConformingBody (pbody->left, sym, body) &&
1622 isConformingBody (pbody->right, sym, body);
1633 assert ("Parser should not have generated this\n");
1635 /*------------------------------------------------------------------*/
1636 /*----------------------------*/
1637 /* comma operator */
1638 /*----------------------------*/
1640 return isConformingBody (pbody->left, sym, body) &&
1641 isConformingBody (pbody->right, sym, body);
1643 /*------------------------------------------------------------------*/
1644 /*----------------------------*/
1646 /*----------------------------*/
1650 /*------------------------------------------------------------------*/
1651 /*----------------------------*/
1652 /* return statement */
1653 /*----------------------------*/
1658 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1663 if (astHasSymbol (pbody->left, sym))
1670 return isConformingBody (pbody->left, sym, body) &&
1671 isConformingBody (pbody->right, sym, body);
1677 /*-----------------------------------------------------------------*/
1678 /* isLoopReversible - takes a for loop as input && returns true */
1679 /* if the for loop is reversible. If yes will set the value of */
1680 /* the loop control var & init value & termination value */
1681 /*-----------------------------------------------------------------*/
1683 isLoopReversible (ast * loop, symbol ** loopCntrl,
1684 ast ** init, ast ** end)
1686 /* if option says don't do it then don't */
1687 if (optimize.noLoopReverse)
1689 /* there are several tests to determine this */
1691 /* for loop has to be of the form
1692 for ( <sym> = <const1> ;
1693 [<sym> < <const2>] ;
1694 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1696 if (!isLoopCountable (AST_FOR (loop, initExpr),
1697 AST_FOR (loop, condExpr),
1698 AST_FOR (loop, loopExpr),
1699 loopCntrl, init, end))
1702 /* now do some serious checking on the body of the loop
1705 return isConformingBody (loop->left, *loopCntrl, loop->left);
1709 /*-----------------------------------------------------------------*/
1710 /* replLoopSym - replace the loop sym by loop sym -1 */
1711 /*-----------------------------------------------------------------*/
1713 replLoopSym (ast * body, symbol * sym)
1716 if (!body || IS_AST_LINK (body))
1719 if (IS_AST_SYM_VALUE (body))
1722 if (isSymbolEqual (AST_SYMBOL (body), sym))
1726 body->opval.op = '-';
1727 body->left = newAst_VALUE (symbolVal (sym));
1728 body->right = newAst_VALUE (constVal ("1"));
1736 replLoopSym (body->left, sym);
1737 replLoopSym (body->right, sym);
1741 /*-----------------------------------------------------------------*/
1742 /* reverseLoop - do the actual loop reversal */
1743 /*-----------------------------------------------------------------*/
1745 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1749 /* create the following tree
1754 if (sym) goto for_continue ;
1757 /* put it together piece by piece */
1758 rloop = newNode (NULLOP,
1759 createIf (newAst_VALUE (symbolVal (sym)),
1761 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1764 newAst_VALUE (symbolVal (sym)),
1767 replLoopSym (loop->left, sym);
1769 rloop = newNode (NULLOP,
1771 newAst_VALUE (symbolVal (sym)),
1772 newNode ('-', end, init)),
1773 createLabel (AST_FOR (loop, continueLabel),
1777 newNode (SUB_ASSIGN,
1778 newAst_VALUE (symbolVal (sym)),
1779 newAst_VALUE (constVal ("1"))),
1782 return decorateType (rloop);
1786 /*-----------------------------------------------------------------*/
1787 /* decorateType - compute type for this tree also does type cheking */
1788 /* this is done bottom up, since type have to flow upwards */
1789 /* it also does constant folding, and paramater checking */
1790 /*-----------------------------------------------------------------*/
1792 decorateType (ast * tree)
1800 /* if already has type then do nothing */
1801 if (tree->decorated)
1804 tree->decorated = 1;
1806 /* print the line */
1807 /* if not block & function */
1808 if (tree->type == EX_OP &&
1809 (tree->opval.op != FUNCTION &&
1810 tree->opval.op != BLOCK &&
1811 tree->opval.op != NULLOP))
1813 filename = tree->filename;
1814 lineno = tree->lineno;
1817 /* if any child is an error | this one is an error do nothing */
1818 if (tree->isError ||
1819 (tree->left && tree->left->isError) ||
1820 (tree->right && tree->right->isError))
1823 /*------------------------------------------------------------------*/
1824 /*----------------------------*/
1825 /* leaf has been reached */
1826 /*----------------------------*/
1827 /* if this is of type value */
1828 /* just get the type */
1829 if (tree->type == EX_VALUE)
1832 if (IS_LITERAL (tree->opval.val->etype))
1835 /* if this is a character array then declare it */
1836 if (IS_ARRAY (tree->opval.val->type))
1837 tree->opval.val = stringToSymbol (tree->opval.val);
1839 /* otherwise just copy the type information */
1840 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1844 if (tree->opval.val->sym)
1846 /* if the undefined flag is set then give error message */
1847 if (tree->opval.val->sym->undefined)
1849 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1851 TTYPE (tree) = TETYPE (tree) =
1852 tree->opval.val->type = tree->opval.val->sym->type =
1853 tree->opval.val->etype = tree->opval.val->sym->etype =
1854 copyLinkChain (INTTYPE);
1859 /* if impilicit i.e. struct/union member then no type */
1860 if (tree->opval.val->sym->implicit)
1861 TTYPE (tree) = TETYPE (tree) = NULL;
1866 /* else copy the type */
1867 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1869 /* and mark it as referenced */
1870 tree->opval.val->sym->isref = 1;
1878 /* if type link for the case of cast */
1879 if (tree->type == EX_LINK)
1881 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1888 dtl = decorateType (tree->left);
1889 /* delay right side for '?' operator since conditional macro expansions might
1891 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1893 /* this is to take care of situations
1894 when the tree gets rewritten */
1895 if (dtl != tree->left)
1897 if (dtr != tree->right)
1901 /* depending on type of operator do */
1903 switch (tree->opval.op)
1905 /*------------------------------------------------------------------*/
1906 /*----------------------------*/
1908 /*----------------------------*/
1911 /* determine which is the array & which the index */
1912 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1915 ast *tempTree = tree->left;
1916 tree->left = tree->right;
1917 tree->right = tempTree;
1920 /* first check if this is a array or a pointer */
1921 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1923 werror (E_NEED_ARRAY_PTR, "[]");
1924 goto errorTreeReturn;
1927 /* check if the type of the idx */
1928 if (!IS_INTEGRAL (RTYPE (tree)))
1930 werror (E_IDX_NOT_INT);
1931 goto errorTreeReturn;
1934 /* if the left is an rvalue then error */
1937 werror (E_LVALUE_REQUIRED, "array access");
1938 goto errorTreeReturn;
1941 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1942 if (IS_PTR(LTYPE(tree))) {
1943 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1947 /*------------------------------------------------------------------*/
1948 /*----------------------------*/
1950 /*----------------------------*/
1952 /* if this is not a structure */
1953 if (!IS_STRUCT (LTYPE (tree)))
1955 werror (E_STRUCT_UNION, ".");
1956 goto errorTreeReturn;
1958 TTYPE (tree) = structElemType (LTYPE (tree),
1959 (tree->right->type == EX_VALUE ?
1960 tree->right->opval.val : NULL));
1961 TETYPE (tree) = getSpec (TTYPE (tree));
1964 /*------------------------------------------------------------------*/
1965 /*----------------------------*/
1966 /* struct/union pointer */
1967 /*----------------------------*/
1969 /* if not pointer to a structure */
1970 if (!IS_PTR (LTYPE (tree)))
1972 werror (E_PTR_REQD);
1973 goto errorTreeReturn;
1976 if (!IS_STRUCT (LTYPE (tree)->next))
1978 werror (E_STRUCT_UNION, "->");
1979 goto errorTreeReturn;
1982 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1983 (tree->right->type == EX_VALUE ?
1984 tree->right->opval.val : NULL));
1985 TETYPE (tree) = getSpec (TTYPE (tree));
1987 /* adjust the storage class */
1988 switch (DCL_TYPE(tree->left->ftype)) {
1992 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
1995 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2000 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2003 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2006 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2015 /*------------------------------------------------------------------*/
2016 /*----------------------------*/
2017 /* ++/-- operation */
2018 /*----------------------------*/
2019 case INC_OP: /* incerement operator unary so left only */
2022 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2023 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2024 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2025 werror (E_CODE_WRITE, "++/--");
2034 /*------------------------------------------------------------------*/
2035 /*----------------------------*/
2037 /*----------------------------*/
2038 case '&': /* can be unary */
2039 /* if right is NULL then unary operation */
2040 if (tree->right) /* not an unary operation */
2043 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2045 werror (E_BITWISE_OP);
2046 werror (W_CONTINUE, "left & right types are ");
2047 printTypeChain (LTYPE (tree), stderr);
2048 fprintf (stderr, ",");
2049 printTypeChain (RTYPE (tree), stderr);
2050 fprintf (stderr, "\n");
2051 goto errorTreeReturn;
2054 /* if they are both literal */
2055 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2057 tree->type = EX_VALUE;
2058 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2059 valFromType (RETYPE (tree)), '&');
2061 tree->right = tree->left = NULL;
2062 TETYPE (tree) = tree->opval.val->etype;
2063 TTYPE (tree) = tree->opval.val->type;
2067 /* see if this is a GETHBIT operation if yes
2070 ast *otree = optimizeGetHbit (tree);
2073 return decorateType (otree);
2077 computeType (LTYPE (tree), RTYPE (tree));
2078 TETYPE (tree) = getSpec (TTYPE (tree));
2080 LRVAL (tree) = RRVAL (tree) = 1;
2084 /*------------------------------------------------------------------*/
2085 /*----------------------------*/
2087 /*----------------------------*/
2089 p->class = DECLARATOR;
2090 /* if bit field then error */
2091 if (IS_BITVAR (tree->left->etype))
2093 werror (E_ILLEGAL_ADDR, "address of bit variable");
2094 goto errorTreeReturn;
2097 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2099 werror (E_ILLEGAL_ADDR, "address of register variable");
2100 goto errorTreeReturn;
2103 if (IS_FUNC (LTYPE (tree)))
2105 werror (E_ILLEGAL_ADDR, "address of function");
2106 goto errorTreeReturn;
2109 if (IS_LITERAL(LTYPE(tree)))
2111 werror (E_ILLEGAL_ADDR, "address of literal");
2112 goto errorTreeReturn;
2117 werror (E_LVALUE_REQUIRED, "address of");
2118 goto errorTreeReturn;
2120 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2122 DCL_TYPE (p) = CPOINTER;
2123 DCL_PTR_CONST (p) = port->mem.code_ro;
2125 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2126 DCL_TYPE (p) = FPOINTER;
2127 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2128 DCL_TYPE (p) = PPOINTER;
2129 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2130 DCL_TYPE (p) = IPOINTER;
2131 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2132 DCL_TYPE (p) = EEPPOINTER;
2133 else if (SPEC_OCLS(tree->left->etype))
2134 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2136 DCL_TYPE (p) = POINTER;
2138 if (IS_AST_SYM_VALUE (tree->left))
2140 AST_SYMBOL (tree->left)->addrtaken = 1;
2141 AST_SYMBOL (tree->left)->allocreq = 1;
2144 p->next = LTYPE (tree);
2146 TETYPE (tree) = getSpec (TTYPE (tree));
2147 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2148 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2153 /*------------------------------------------------------------------*/
2154 /*----------------------------*/
2156 /*----------------------------*/
2158 /* if the rewrite succeeds then don't go any furthur */
2160 ast *wtree = optimizeRRCRLC (tree);
2162 return decorateType (wtree);
2164 /*------------------------------------------------------------------*/
2165 /*----------------------------*/
2167 /*----------------------------*/
2169 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2171 werror (E_BITWISE_OP);
2172 werror (W_CONTINUE, "left & right types are ");
2173 printTypeChain (LTYPE (tree), stderr);
2174 fprintf (stderr, ",");
2175 printTypeChain (RTYPE (tree), stderr);
2176 fprintf (stderr, "\n");
2177 goto errorTreeReturn;
2180 /* if they are both literal then */
2181 /* rewrite the tree */
2182 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2184 tree->type = EX_VALUE;
2185 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2186 valFromType (RETYPE (tree)),
2188 tree->right = tree->left = NULL;
2189 TETYPE (tree) = tree->opval.val->etype;
2190 TTYPE (tree) = tree->opval.val->type;
2193 LRVAL (tree) = RRVAL (tree) = 1;
2194 TETYPE (tree) = getSpec (TTYPE (tree) =
2195 computeType (LTYPE (tree),
2198 /*------------------------------------------------------------------*/
2199 /*----------------------------*/
2201 /*----------------------------*/
2203 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2205 werror (E_INVALID_OP, "divide");
2206 goto errorTreeReturn;
2208 /* if they are both literal then */
2209 /* rewrite the tree */
2210 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2212 tree->type = EX_VALUE;
2213 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2214 valFromType (RETYPE (tree)));
2215 tree->right = tree->left = NULL;
2216 TETYPE (tree) = getSpec (TTYPE (tree) =
2217 tree->opval.val->type);
2220 LRVAL (tree) = RRVAL (tree) = 1;
2221 TETYPE (tree) = getSpec (TTYPE (tree) =
2222 computeType (LTYPE (tree),
2226 /*------------------------------------------------------------------*/
2227 /*----------------------------*/
2229 /*----------------------------*/
2231 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2233 werror (E_BITWISE_OP);
2234 werror (W_CONTINUE, "left & right types are ");
2235 printTypeChain (LTYPE (tree), stderr);
2236 fprintf (stderr, ",");
2237 printTypeChain (RTYPE (tree), stderr);
2238 fprintf (stderr, "\n");
2239 goto errorTreeReturn;
2241 /* if they are both literal then */
2242 /* rewrite the tree */
2243 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2245 tree->type = EX_VALUE;
2246 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2247 valFromType (RETYPE (tree)));
2248 tree->right = tree->left = NULL;
2249 TETYPE (tree) = getSpec (TTYPE (tree) =
2250 tree->opval.val->type);
2253 LRVAL (tree) = RRVAL (tree) = 1;
2254 TETYPE (tree) = getSpec (TTYPE (tree) =
2255 computeType (LTYPE (tree),
2259 /*------------------------------------------------------------------*/
2260 /*----------------------------*/
2261 /* address dereference */
2262 /*----------------------------*/
2263 case '*': /* can be unary : if right is null then unary operation */
2266 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2268 werror (E_PTR_REQD);
2269 goto errorTreeReturn;
2274 werror (E_LVALUE_REQUIRED, "pointer deref");
2275 goto errorTreeReturn;
2277 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2278 LTYPE (tree)->next : NULL);
2279 TETYPE (tree) = getSpec (TTYPE (tree));
2280 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2284 /*------------------------------------------------------------------*/
2285 /*----------------------------*/
2286 /* multiplication */
2287 /*----------------------------*/
2288 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2290 werror (E_INVALID_OP, "multiplication");
2291 goto errorTreeReturn;
2294 /* if they are both literal then */
2295 /* rewrite the tree */
2296 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2298 tree->type = EX_VALUE;
2299 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2300 valFromType (RETYPE (tree)));
2301 tree->right = tree->left = NULL;
2302 TETYPE (tree) = getSpec (TTYPE (tree) =
2303 tree->opval.val->type);
2307 /* if left is a literal exchange left & right */
2308 if (IS_LITERAL (LTYPE (tree)))
2310 ast *tTree = tree->left;
2311 tree->left = tree->right;
2312 tree->right = tTree;
2315 LRVAL (tree) = RRVAL (tree) = 1;
2316 /* promote result to int if left & right are char
2317 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2318 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2319 TETYPE (tree) = getSpec (TTYPE (tree) =
2320 computeType (LTYPE (tree),
2322 SPEC_NOUN(TETYPE(tree)) = V_INT;
2324 TETYPE (tree) = getSpec (TTYPE (tree) =
2325 computeType (LTYPE (tree),
2330 /*------------------------------------------------------------------*/
2331 /*----------------------------*/
2332 /* unary '+' operator */
2333 /*----------------------------*/
2338 if (!IS_INTEGRAL (LTYPE (tree)))
2340 werror (E_UNARY_OP, '+');
2341 goto errorTreeReturn;
2344 /* if left is a literal then do it */
2345 if (IS_LITERAL (LTYPE (tree)))
2347 tree->type = EX_VALUE;
2348 tree->opval.val = valFromType (LETYPE (tree));
2350 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2354 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2358 /*------------------------------------------------------------------*/
2359 /*----------------------------*/
2361 /*----------------------------*/
2363 /* this is not a unary operation */
2364 /* if both pointers then problem */
2365 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2366 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2368 werror (E_PTR_PLUS_PTR);
2369 goto errorTreeReturn;
2372 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2373 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2375 werror (E_PLUS_INVALID, "+");
2376 goto errorTreeReturn;
2379 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2380 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2382 werror (E_PLUS_INVALID, "+");
2383 goto errorTreeReturn;
2385 /* if they are both literal then */
2386 /* rewrite the tree */
2387 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2389 tree->type = EX_VALUE;
2390 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2391 valFromType (RETYPE (tree)));
2392 tree->right = tree->left = NULL;
2393 TETYPE (tree) = getSpec (TTYPE (tree) =
2394 tree->opval.val->type);
2398 /* if the right is a pointer or left is a literal
2399 xchange left & right */
2400 if (IS_ARRAY (RTYPE (tree)) ||
2401 IS_PTR (RTYPE (tree)) ||
2402 IS_LITERAL (LTYPE (tree)))
2404 ast *tTree = tree->left;
2405 tree->left = tree->right;
2406 tree->right = tTree;
2409 LRVAL (tree) = RRVAL (tree) = 1;
2410 /* if the left is a pointer */
2411 if (IS_PTR (LTYPE (tree)))
2412 TETYPE (tree) = getSpec (TTYPE (tree) =
2415 TETYPE (tree) = getSpec (TTYPE (tree) =
2416 computeType (LTYPE (tree),
2420 /*------------------------------------------------------------------*/
2421 /*----------------------------*/
2423 /*----------------------------*/
2424 case '-': /* can be unary */
2425 /* if right is null then unary */
2429 if (!IS_ARITHMETIC (LTYPE (tree)))
2431 werror (E_UNARY_OP, tree->opval.op);
2432 goto errorTreeReturn;
2435 /* if left is a literal then do it */
2436 if (IS_LITERAL (LTYPE (tree)))
2438 tree->type = EX_VALUE;
2439 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2441 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2442 SPEC_USIGN(TETYPE(tree)) = 0;
2446 TTYPE (tree) = LTYPE (tree);
2450 /*------------------------------------------------------------------*/
2451 /*----------------------------*/
2453 /*----------------------------*/
2455 if (!(IS_PTR (LTYPE (tree)) ||
2456 IS_ARRAY (LTYPE (tree)) ||
2457 IS_ARITHMETIC (LTYPE (tree))))
2459 werror (E_PLUS_INVALID, "-");
2460 goto errorTreeReturn;
2463 if (!(IS_PTR (RTYPE (tree)) ||
2464 IS_ARRAY (RTYPE (tree)) ||
2465 IS_ARITHMETIC (RTYPE (tree))))
2467 werror (E_PLUS_INVALID, "-");
2468 goto errorTreeReturn;
2471 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2472 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2473 IS_INTEGRAL (RTYPE (tree))))
2475 werror (E_PLUS_INVALID, "-");
2476 goto errorTreeReturn;
2479 /* if they are both literal then */
2480 /* rewrite the tree */
2481 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2483 tree->type = EX_VALUE;
2484 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2485 valFromType (RETYPE (tree)));
2486 tree->right = tree->left = NULL;
2487 TETYPE (tree) = getSpec (TTYPE (tree) =
2488 tree->opval.val->type);
2492 /* if the left & right are equal then zero */
2493 if (isAstEqual (tree->left, tree->right))
2495 tree->type = EX_VALUE;
2496 tree->left = tree->right = NULL;
2497 tree->opval.val = constVal ("0");
2498 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2502 /* if both of them are pointers or arrays then */
2503 /* the result is going to be an integer */
2504 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2505 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2506 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2508 /* if only the left is a pointer */
2509 /* then result is a pointer */
2510 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2511 TETYPE (tree) = getSpec (TTYPE (tree) =
2514 TETYPE (tree) = getSpec (TTYPE (tree) =
2515 computeType (LTYPE (tree),
2517 LRVAL (tree) = RRVAL (tree) = 1;
2520 /*------------------------------------------------------------------*/
2521 /*----------------------------*/
2523 /*----------------------------*/
2525 /* can be only integral type */
2526 if (!IS_INTEGRAL (LTYPE (tree)))
2528 werror (E_UNARY_OP, tree->opval.op);
2529 goto errorTreeReturn;
2532 /* if left is a literal then do it */
2533 if (IS_LITERAL (LTYPE (tree)))
2535 tree->type = EX_VALUE;
2536 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2538 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2542 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2545 /*------------------------------------------------------------------*/
2546 /*----------------------------*/
2548 /*----------------------------*/
2550 /* can be pointer */
2551 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2552 !IS_PTR (LTYPE (tree)) &&
2553 !IS_ARRAY (LTYPE (tree)))
2555 werror (E_UNARY_OP, tree->opval.op);
2556 goto errorTreeReturn;
2559 /* if left is a literal then do it */
2560 if (IS_LITERAL (LTYPE (tree)))
2562 tree->type = EX_VALUE;
2563 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2565 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2569 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2572 /*------------------------------------------------------------------*/
2573 /*----------------------------*/
2575 /*----------------------------*/
2578 TTYPE (tree) = LTYPE (tree);
2579 TETYPE (tree) = LETYPE (tree);
2583 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2588 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2590 werror (E_SHIFT_OP_INVALID);
2591 werror (W_CONTINUE, "left & right types are ");
2592 printTypeChain (LTYPE (tree), stderr);
2593 fprintf (stderr, ",");
2594 printTypeChain (RTYPE (tree), stderr);
2595 fprintf (stderr, "\n");
2596 goto errorTreeReturn;
2599 /* if they are both literal then */
2600 /* rewrite the tree */
2601 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2603 tree->type = EX_VALUE;
2604 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2605 valFromType (RETYPE (tree)),
2606 (tree->opval.op == LEFT_OP ? 1 : 0));
2607 tree->right = tree->left = NULL;
2608 TETYPE (tree) = getSpec (TTYPE (tree) =
2609 tree->opval.val->type);
2612 /* if only the right side is a literal & we are
2613 shifting more than size of the left operand then zero */
2614 if (IS_LITERAL (RTYPE (tree)) &&
2615 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2616 (getSize (LTYPE (tree)) * 8))
2618 werror (W_SHIFT_CHANGED,
2619 (tree->opval.op == LEFT_OP ? "left" : "right"));
2620 tree->type = EX_VALUE;
2621 tree->left = tree->right = NULL;
2622 tree->opval.val = constVal ("0");
2623 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2626 LRVAL (tree) = RRVAL (tree) = 1;
2627 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2629 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2633 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2637 /*------------------------------------------------------------------*/
2638 /*----------------------------*/
2640 /*----------------------------*/
2641 case CAST: /* change the type */
2642 /* cannot cast to an aggregate type */
2643 if (IS_AGGREGATE (LTYPE (tree)))
2645 werror (E_CAST_ILLEGAL);
2646 goto errorTreeReturn;
2649 /* make sure the type is complete and sane */
2650 checkTypeSanity(LETYPE(tree), "(cast)");
2653 /* if the right is a literal replace the tree */
2654 if (IS_LITERAL (RETYPE (tree))) {
2655 if (!IS_PTR (LTYPE (tree))) {
2656 tree->type = EX_VALUE;
2658 valCastLiteral (LTYPE (tree),
2659 floatFromVal (valFromType (RETYPE (tree))));
2662 TTYPE (tree) = tree->opval.val->type;
2663 tree->values.literalFromCast = 1;
2664 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2665 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2666 sym_link *rest = LTYPE(tree)->next;
2667 werror(W_LITERAL_GENERIC);
2668 TTYPE(tree) = newLink();
2669 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2670 TTYPE(tree)->next = rest;
2671 tree->left->opval.lnk = TTYPE(tree);
2674 TTYPE (tree) = LTYPE (tree);
2678 TTYPE (tree) = LTYPE (tree);
2682 /* if pointer to struct then check names */
2683 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2684 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2685 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2686 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2688 /* if the right is a literal replace the tree */
2689 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2690 tree->type = EX_VALUE;
2692 valCastLiteral (LTYPE (tree),
2693 floatFromVal (valFromType (RETYPE (tree))));
2696 TTYPE (tree) = tree->opval.val->type;
2697 tree->values.literalFromCast = 1;
2699 TTYPE (tree) = LTYPE (tree);
2703 TETYPE (tree) = getSpec (TTYPE (tree));
2707 /*------------------------------------------------------------------*/
2708 /*----------------------------*/
2709 /* logical &&, || */
2710 /*----------------------------*/
2713 /* each must me arithmetic type or be a pointer */
2714 if (!IS_PTR (LTYPE (tree)) &&
2715 !IS_ARRAY (LTYPE (tree)) &&
2716 !IS_INTEGRAL (LTYPE (tree)))
2718 werror (E_COMPARE_OP);
2719 goto errorTreeReturn;
2722 if (!IS_PTR (RTYPE (tree)) &&
2723 !IS_ARRAY (RTYPE (tree)) &&
2724 !IS_INTEGRAL (RTYPE (tree)))
2726 werror (E_COMPARE_OP);
2727 goto errorTreeReturn;
2729 /* if they are both literal then */
2730 /* rewrite the tree */
2731 if (IS_LITERAL (RTYPE (tree)) &&
2732 IS_LITERAL (LTYPE (tree)))
2734 tree->type = EX_VALUE;
2735 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2736 valFromType (RETYPE (tree)),
2738 tree->right = tree->left = NULL;
2739 TETYPE (tree) = getSpec (TTYPE (tree) =
2740 tree->opval.val->type);
2743 LRVAL (tree) = RRVAL (tree) = 1;
2744 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2747 /*------------------------------------------------------------------*/
2748 /*----------------------------*/
2749 /* comparison operators */
2750 /*----------------------------*/
2758 ast *lt = optimizeCompare (tree);
2764 /* if they are pointers they must be castable */
2765 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2767 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2769 werror (E_COMPARE_OP);
2770 fprintf (stderr, "comparing type ");
2771 printTypeChain (LTYPE (tree), stderr);
2772 fprintf (stderr, "to type ");
2773 printTypeChain (RTYPE (tree), stderr);
2774 fprintf (stderr, "\n");
2775 goto errorTreeReturn;
2778 /* else they should be promotable to one another */
2781 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2782 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2784 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2786 werror (E_COMPARE_OP);
2787 fprintf (stderr, "comparing type ");
2788 printTypeChain (LTYPE (tree), stderr);
2789 fprintf (stderr, "to type ");
2790 printTypeChain (RTYPE (tree), stderr);
2791 fprintf (stderr, "\n");
2792 goto errorTreeReturn;
2795 /* if unsigned value < 0 then always false */
2796 /* if (unsigned value) > 0 then (unsigned value) */
2797 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2798 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2800 if (tree->opval.op == '<') {
2803 if (tree->opval.op == '>') {
2807 /* if they are both literal then */
2808 /* rewrite the tree */
2809 if (IS_LITERAL (RTYPE (tree)) &&
2810 IS_LITERAL (LTYPE (tree)))
2812 tree->type = EX_VALUE;
2813 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2814 valFromType (RETYPE (tree)),
2816 tree->right = tree->left = NULL;
2817 TETYPE (tree) = getSpec (TTYPE (tree) =
2818 tree->opval.val->type);
2821 LRVAL (tree) = RRVAL (tree) = 1;
2822 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2825 /*------------------------------------------------------------------*/
2826 /*----------------------------*/
2828 /*----------------------------*/
2829 case SIZEOF: /* evaluate wihout code generation */
2830 /* change the type to a integer */
2831 tree->type = EX_VALUE;
2832 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2833 tree->opval.val = constVal (buffer);
2834 tree->right = tree->left = NULL;
2835 TETYPE (tree) = getSpec (TTYPE (tree) =
2836 tree->opval.val->type);
2839 /*------------------------------------------------------------------*/
2840 /*----------------------------*/
2842 /*----------------------------*/
2844 /* return typeof enum value */
2845 tree->type = EX_VALUE;
2848 if (IS_SPEC(tree->right->ftype)) {
2849 switch (SPEC_NOUN(tree->right->ftype)) {
2851 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2852 else typeofv = TYPEOF_INT;
2855 typeofv = TYPEOF_FLOAT;
2858 typeofv = TYPEOF_CHAR;
2861 typeofv = TYPEOF_VOID;
2864 typeofv = TYPEOF_STRUCT;
2867 typeofv = TYPEOF_BIT;
2870 typeofv = TYPEOF_SBIT;
2876 switch (DCL_TYPE(tree->right->ftype)) {
2878 typeofv = TYPEOF_POINTER;
2881 typeofv = TYPEOF_FPOINTER;
2884 typeofv = TYPEOF_CPOINTER;
2887 typeofv = TYPEOF_GPOINTER;
2890 typeofv = TYPEOF_PPOINTER;
2893 typeofv = TYPEOF_IPOINTER;
2896 typeofv = TYPEOF_ARRAY;
2899 typeofv = TYPEOF_FUNCTION;
2905 sprintf (buffer, "%d", typeofv);
2906 tree->opval.val = constVal (buffer);
2907 tree->right = tree->left = NULL;
2908 TETYPE (tree) = getSpec (TTYPE (tree) =
2909 tree->opval.val->type);
2912 /*------------------------------------------------------------------*/
2913 /*----------------------------*/
2914 /* conditional operator '?' */
2915 /*----------------------------*/
2917 /* the type is value of the colon operator (on the right) */
2918 assert(IS_COLON_OP(tree->right));
2919 /* if already known then replace the tree : optimizer will do it
2920 but faster to do it here */
2921 if (IS_LITERAL (LTYPE(tree))) {
2922 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2923 return decorateType(tree->right->left) ;
2925 return decorateType(tree->right->right) ;
2928 tree->right = decorateType(tree->right);
2929 TTYPE (tree) = RTYPE(tree);
2930 TETYPE (tree) = getSpec (TTYPE (tree));
2935 /* if they don't match we have a problem */
2936 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2938 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2939 goto errorTreeReturn;
2942 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2943 TETYPE (tree) = getSpec (TTYPE (tree));
2947 /*------------------------------------------------------------------*/
2948 /*----------------------------*/
2949 /* assignment operators */
2950 /*----------------------------*/
2953 /* for these it must be both must be integral */
2954 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2955 !IS_ARITHMETIC (RTYPE (tree)))
2957 werror (E_OPS_INTEGRAL);
2958 goto errorTreeReturn;
2961 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2963 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2964 werror (E_CODE_WRITE, " ");
2968 werror (E_LVALUE_REQUIRED, "*= or /=");
2969 goto errorTreeReturn;
2980 /* for these it must be both must be integral */
2981 if (!IS_INTEGRAL (LTYPE (tree)) ||
2982 !IS_INTEGRAL (RTYPE (tree)))
2984 werror (E_OPS_INTEGRAL);
2985 goto errorTreeReturn;
2988 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2990 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2991 werror (E_CODE_WRITE, " ");
2995 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2996 goto errorTreeReturn;
3002 /*------------------------------------------------------------------*/
3003 /*----------------------------*/
3005 /*----------------------------*/
3007 if (!(IS_PTR (LTYPE (tree)) ||
3008 IS_ARITHMETIC (LTYPE (tree))))
3010 werror (E_PLUS_INVALID, "-=");
3011 goto errorTreeReturn;
3014 if (!(IS_PTR (RTYPE (tree)) ||
3015 IS_ARITHMETIC (RTYPE (tree))))
3017 werror (E_PLUS_INVALID, "-=");
3018 goto errorTreeReturn;
3021 TETYPE (tree) = getSpec (TTYPE (tree) =
3022 computeType (LTYPE (tree),
3025 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3026 werror (E_CODE_WRITE, " ");
3030 werror (E_LVALUE_REQUIRED, "-=");
3031 goto errorTreeReturn;
3037 /*------------------------------------------------------------------*/
3038 /*----------------------------*/
3040 /*----------------------------*/
3042 /* this is not a unary operation */
3043 /* if both pointers then problem */
3044 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3046 werror (E_PTR_PLUS_PTR);
3047 goto errorTreeReturn;
3050 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3052 werror (E_PLUS_INVALID, "+=");
3053 goto errorTreeReturn;
3056 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3058 werror (E_PLUS_INVALID, "+=");
3059 goto errorTreeReturn;
3062 TETYPE (tree) = getSpec (TTYPE (tree) =
3063 computeType (LTYPE (tree),
3066 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3067 werror (E_CODE_WRITE, " ");
3071 werror (E_LVALUE_REQUIRED, "+=");
3072 goto errorTreeReturn;
3075 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3076 tree->opval.op = '=';
3080 /*------------------------------------------------------------------*/
3081 /*----------------------------*/
3082 /* straight assignemnt */
3083 /*----------------------------*/
3085 /* cannot be an aggregate */
3086 if (IS_AGGREGATE (LTYPE (tree)))
3088 werror (E_AGGR_ASSIGN);
3089 goto errorTreeReturn;
3092 /* they should either match or be castable */
3093 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3095 werror (E_TYPE_MISMATCH, "assignment", " ");
3096 fprintf (stderr, "type --> '");
3097 printTypeChain (RTYPE (tree), stderr);
3098 fprintf (stderr, "' ");
3099 fprintf (stderr, "assigned to type --> '");
3100 printTypeChain (LTYPE (tree), stderr);
3101 fprintf (stderr, "'\n");
3102 goto errorTreeReturn;
3105 /* if the left side of the tree is of type void
3106 then report error */
3107 if (IS_VOID (LTYPE (tree)))
3109 werror (E_CAST_ZERO);
3110 printFromToType(RTYPE(tree), LTYPE(tree));
3113 TETYPE (tree) = getSpec (TTYPE (tree) =
3117 if (!tree->initMode ) {
3118 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3119 werror (E_CODE_WRITE, " ");
3123 werror (E_LVALUE_REQUIRED, "=");
3124 goto errorTreeReturn;
3129 /*------------------------------------------------------------------*/
3130 /*----------------------------*/
3131 /* comma operator */
3132 /*----------------------------*/
3134 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3137 /*------------------------------------------------------------------*/
3138 /*----------------------------*/
3140 /*----------------------------*/
3144 if (processParms (tree->left,
3145 FUNC_ARGS(tree->left->ftype),
3146 tree->right, &parmNumber, TRUE)) {
3147 goto errorTreeReturn;
3150 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3151 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3153 //FUNC_ARGS(tree->left->ftype) =
3154 //reverseVal (FUNC_ARGS(tree->left->ftype));
3155 reverseParms (tree->right);
3158 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3161 /*------------------------------------------------------------------*/
3162 /*----------------------------*/
3163 /* return statement */
3164 /*----------------------------*/
3169 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3171 werror (W_RETURN_MISMATCH);
3172 printFromToType (RTYPE(tree), currFunc->type->next);
3173 goto errorTreeReturn;
3176 if (IS_VOID (currFunc->type->next)
3178 !IS_VOID (RTYPE (tree)))
3180 werror (E_FUNC_VOID);
3181 goto errorTreeReturn;
3184 /* if there is going to be a casing required then add it */
3185 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3188 decorateType (newNode (CAST,
3189 newAst_LINK (copyLinkChain (currFunc->type->next)),
3198 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3200 werror (E_VOID_FUNC, currFunc->name);
3201 goto errorTreeReturn;
3204 TTYPE (tree) = TETYPE (tree) = NULL;
3207 /*------------------------------------------------------------------*/
3208 /*----------------------------*/
3209 /* switch statement */
3210 /*----------------------------*/
3212 /* the switch value must be an integer */
3213 if (!IS_INTEGRAL (LTYPE (tree)))
3215 werror (E_SWITCH_NON_INTEGER);
3216 goto errorTreeReturn;
3219 TTYPE (tree) = TETYPE (tree) = NULL;
3222 /*------------------------------------------------------------------*/
3223 /*----------------------------*/
3225 /*----------------------------*/
3227 tree->left = backPatchLabels (tree->left,
3230 TTYPE (tree) = TETYPE (tree) = NULL;
3233 /*------------------------------------------------------------------*/
3234 /*----------------------------*/
3236 /*----------------------------*/
3239 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3240 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3241 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3243 /* if the for loop is reversible then
3244 reverse it otherwise do what we normally
3250 if (isLoopReversible (tree, &sym, &init, &end))
3251 return reverseLoop (tree, sym, init, end);
3253 return decorateType (createFor (AST_FOR (tree, trueLabel),
3254 AST_FOR (tree, continueLabel),
3255 AST_FOR (tree, falseLabel),
3256 AST_FOR (tree, condLabel),
3257 AST_FOR (tree, initExpr),
3258 AST_FOR (tree, condExpr),
3259 AST_FOR (tree, loopExpr),
3263 TTYPE (tree) = TETYPE (tree) = NULL;
3267 /* some error found this tree will be killed */
3269 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3270 tree->opval.op = NULLOP;
3276 /*-----------------------------------------------------------------*/
3277 /* sizeofOp - processes size of operation */
3278 /*-----------------------------------------------------------------*/
3280 sizeofOp (sym_link * type)
3284 /* make sure the type is complete and sane */
3285 checkTypeSanity(type, "(sizeof)");
3287 /* get the size and convert it to character */
3288 sprintf (buff, "%d", getSize (type));
3290 /* now convert into value */
3291 return constVal (buff);
3295 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3296 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3297 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3298 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3299 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3300 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3301 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3303 /*-----------------------------------------------------------------*/
3304 /* backPatchLabels - change and or not operators to flow control */
3305 /*-----------------------------------------------------------------*/
3307 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3313 if (!(IS_ANDORNOT (tree)))
3316 /* if this an and */
3319 static int localLbl = 0;
3322 sprintf (buffer, "_and_%d", localLbl++);
3323 localLabel = newSymbol (buffer, NestLevel);
3325 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3327 /* if left is already a IFX then just change the if true label in that */
3328 if (!IS_IFX (tree->left))
3329 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3331 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3332 /* right is a IFX then just join */
3333 if (IS_IFX (tree->right))
3334 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3336 tree->right = createLabel (localLabel, tree->right);
3337 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3339 return newNode (NULLOP, tree->left, tree->right);
3342 /* if this is an or operation */
3345 static int localLbl = 0;
3348 sprintf (buffer, "_or_%d", localLbl++);
3349 localLabel = newSymbol (buffer, NestLevel);
3351 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3353 /* if left is already a IFX then just change the if true label in that */
3354 if (!IS_IFX (tree->left))
3355 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3357 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3358 /* right is a IFX then just join */
3359 if (IS_IFX (tree->right))
3360 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3362 tree->right = createLabel (localLabel, tree->right);
3363 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3365 return newNode (NULLOP, tree->left, tree->right);
3371 int wasnot = IS_NOT (tree->left);
3372 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3374 /* if the left is already a IFX */
3375 if (!IS_IFX (tree->left))
3376 tree->left = newNode (IFX, tree->left, NULL);
3380 tree->left->trueLabel = trueLabel;
3381 tree->left->falseLabel = falseLabel;
3385 tree->left->trueLabel = falseLabel;
3386 tree->left->falseLabel = trueLabel;
3393 tree->trueLabel = trueLabel;
3394 tree->falseLabel = falseLabel;
3401 /*-----------------------------------------------------------------*/
3402 /* createBlock - create expression tree for block */
3403 /*-----------------------------------------------------------------*/
3405 createBlock (symbol * decl, ast * body)
3409 /* if the block has nothing */
3413 ex = newNode (BLOCK, NULL, body);
3414 ex->values.sym = decl;
3416 ex->right = ex->right;
3422 /*-----------------------------------------------------------------*/
3423 /* createLabel - creates the expression tree for labels */
3424 /*-----------------------------------------------------------------*/
3426 createLabel (symbol * label, ast * stmnt)
3429 char name[SDCC_NAME_MAX + 1];
3432 /* must create fresh symbol if the symbol name */
3433 /* exists in the symbol table, since there can */
3434 /* be a variable with the same name as the labl */
3435 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3436 (csym->level == label->level))
3437 label = newSymbol (label->name, label->level);
3439 /* change the name before putting it in add _ */
3440 sprintf (name, "%s", label->name);
3442 /* put the label in the LabelSymbol table */
3443 /* but first check if a label of the same */
3445 if ((csym = findSym (LabelTab, NULL, name)))
3446 werror (E_DUPLICATE_LABEL, label->name);
3448 addSym (LabelTab, label, name, label->level, 0, 0);
3451 label->key = labelKey++;
3452 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3458 /*-----------------------------------------------------------------*/
3459 /* createCase - generates the parsetree for a case statement */
3460 /*-----------------------------------------------------------------*/
3462 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3464 char caseLbl[SDCC_NAME_MAX + 1];
3468 /* if the switch statement does not exist */
3469 /* then case is out of context */
3472 werror (E_CASE_CONTEXT);
3476 caseVal = decorateType (resolveSymbols (caseVal));
3477 /* if not a constant then error */
3478 if (!IS_LITERAL (caseVal->ftype))
3480 werror (E_CASE_CONSTANT);
3484 /* if not a integer than error */
3485 if (!IS_INTEGRAL (caseVal->ftype))
3487 werror (E_CASE_NON_INTEGER);
3491 /* find the end of the switch values chain */
3492 if (!(val = swStat->values.switchVals.swVals))
3493 swStat->values.switchVals.swVals = caseVal->opval.val;
3496 /* also order the cases according to value */
3498 int cVal = (int) floatFromVal (caseVal->opval.val);
3499 while (val && (int) floatFromVal (val) < cVal)
3505 /* if we reached the end then */
3508 pval->next = caseVal->opval.val;
3512 /* we found a value greater than */
3513 /* the current value we must add this */
3514 /* before the value */
3515 caseVal->opval.val->next = val;
3517 /* if this was the first in chain */
3518 if (swStat->values.switchVals.swVals == val)
3519 swStat->values.switchVals.swVals =
3522 pval->next = caseVal->opval.val;
3527 /* create the case label */
3528 sprintf (caseLbl, "_case_%d_%d",
3529 swStat->values.switchVals.swNum,
3530 (int) floatFromVal (caseVal->opval.val));
3532 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3537 /*-----------------------------------------------------------------*/
3538 /* createDefault - creates the parse tree for the default statement */
3539 /*-----------------------------------------------------------------*/
3541 createDefault (ast * swStat, ast * stmnt)
3543 char defLbl[SDCC_NAME_MAX + 1];
3545 /* if the switch statement does not exist */
3546 /* then case is out of context */
3549 werror (E_CASE_CONTEXT);
3553 /* turn on the default flag */
3554 swStat->values.switchVals.swDefault = 1;
3556 /* create the label */
3557 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3558 return createLabel (newSymbol (defLbl, 0), stmnt);
3561 /*-----------------------------------------------------------------*/
3562 /* createIf - creates the parsetree for the if statement */
3563 /*-----------------------------------------------------------------*/
3565 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3567 static int Lblnum = 0;
3569 symbol *ifTrue, *ifFalse, *ifEnd;
3571 /* if neither exists */
3572 if (!elseBody && !ifBody) {
3573 // if there are no side effects (i++, j() etc)
3574 if (!hasSEFcalls(condAst)) {
3579 /* create the labels */
3580 sprintf (buffer, "_iffalse_%d", Lblnum);
3581 ifFalse = newSymbol (buffer, NestLevel);
3582 /* if no else body then end == false */
3587 sprintf (buffer, "_ifend_%d", Lblnum);
3588 ifEnd = newSymbol (buffer, NestLevel);
3591 sprintf (buffer, "_iftrue_%d", Lblnum);
3592 ifTrue = newSymbol (buffer, NestLevel);
3596 /* attach the ifTrue label to the top of it body */
3597 ifBody = createLabel (ifTrue, ifBody);
3598 /* attach a goto end to the ifBody if else is present */
3601 ifBody = newNode (NULLOP, ifBody,
3603 newAst_VALUE (symbolVal (ifEnd)),
3605 /* put the elseLabel on the else body */
3606 elseBody = createLabel (ifFalse, elseBody);
3607 /* out the end at the end of the body */
3608 elseBody = newNode (NULLOP,
3610 createLabel (ifEnd, NULL));
3614 ifBody = newNode (NULLOP, ifBody,
3615 createLabel (ifFalse, NULL));
3617 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3618 if (IS_IFX (condAst))
3621 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3623 return newNode (NULLOP, ifTree,
3624 newNode (NULLOP, ifBody, elseBody));
3628 /*-----------------------------------------------------------------*/
3629 /* createDo - creates parse tree for do */
3632 /* _docontinue_n: */
3633 /* condition_expression +-> trueLabel -> _dobody_n */
3635 /* +-> falseLabel-> _dobreak_n */
3637 /*-----------------------------------------------------------------*/
3639 createDo (symbol * trueLabel, symbol * continueLabel,
3640 symbol * falseLabel, ast * condAst, ast * doBody)
3645 /* if the body does not exist then it is simple */
3648 condAst = backPatchLabels (condAst, continueLabel, NULL);
3649 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3650 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3651 doTree->trueLabel = continueLabel;
3652 doTree->falseLabel = NULL;
3656 /* otherwise we have a body */
3657 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3659 /* attach the body label to the top */
3660 doBody = createLabel (trueLabel, doBody);
3661 /* attach the continue label to end of body */
3662 doBody = newNode (NULLOP, doBody,
3663 createLabel (continueLabel, NULL));
3665 /* now put the break label at the end */
3666 if (IS_IFX (condAst))
3669 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3671 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3673 /* putting it together */
3674 return newNode (NULLOP, doBody, doTree);
3677 /*-----------------------------------------------------------------*/
3678 /* createFor - creates parse tree for 'for' statement */
3681 /* condExpr +-> trueLabel -> _forbody_n */
3683 /* +-> falseLabel-> _forbreak_n */
3686 /* _forcontinue_n: */
3688 /* goto _forcond_n ; */
3690 /*-----------------------------------------------------------------*/
3692 createFor (symbol * trueLabel, symbol * continueLabel,
3693 symbol * falseLabel, symbol * condLabel,
3694 ast * initExpr, ast * condExpr, ast * loopExpr,
3699 /* if loopexpression not present then we can generate it */
3700 /* the same way as a while */
3702 return newNode (NULLOP, initExpr,
3703 createWhile (trueLabel, continueLabel,
3704 falseLabel, condExpr, forBody));
3705 /* vanilla for statement */
3706 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3708 if (condExpr && !IS_IFX (condExpr))
3709 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3712 /* attach condition label to condition */
3713 condExpr = createLabel (condLabel, condExpr);
3715 /* attach body label to body */
3716 forBody = createLabel (trueLabel, forBody);
3718 /* attach continue to forLoop expression & attach */
3719 /* goto the forcond @ and of loopExpression */
3720 loopExpr = createLabel (continueLabel,
3724 newAst_VALUE (symbolVal (condLabel)),
3726 /* now start putting them together */
3727 forTree = newNode (NULLOP, initExpr, condExpr);
3728 forTree = newNode (NULLOP, forTree, forBody);
3729 forTree = newNode (NULLOP, forTree, loopExpr);
3730 /* finally add the break label */
3731 forTree = newNode (NULLOP, forTree,
3732 createLabel (falseLabel, NULL));
3736 /*-----------------------------------------------------------------*/
3737 /* createWhile - creates parse tree for while statement */
3738 /* the while statement will be created as follows */
3740 /* _while_continue_n: */
3741 /* condition_expression +-> trueLabel -> _while_boby_n */
3743 /* +-> falseLabel -> _while_break_n */
3744 /* _while_body_n: */
3746 /* goto _while_continue_n */
3747 /* _while_break_n: */
3748 /*-----------------------------------------------------------------*/
3750 createWhile (symbol * trueLabel, symbol * continueLabel,
3751 symbol * falseLabel, ast * condExpr, ast * whileBody)
3755 /* put the continue label */
3756 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3757 condExpr = createLabel (continueLabel, condExpr);
3758 condExpr->lineno = 0;
3760 /* put the body label in front of the body */
3761 whileBody = createLabel (trueLabel, whileBody);
3762 whileBody->lineno = 0;
3763 /* put a jump to continue at the end of the body */
3764 /* and put break label at the end of the body */
3765 whileBody = newNode (NULLOP,
3768 newAst_VALUE (symbolVal (continueLabel)),
3769 createLabel (falseLabel, NULL)));
3771 /* put it all together */
3772 if (IS_IFX (condExpr))
3773 whileTree = condExpr;
3776 whileTree = newNode (IFX, condExpr, NULL);
3777 /* put the true & false labels in place */
3778 whileTree->trueLabel = trueLabel;
3779 whileTree->falseLabel = falseLabel;
3782 return newNode (NULLOP, whileTree, whileBody);
3785 /*-----------------------------------------------------------------*/
3786 /* optimizeGetHbit - get highest order bit of the expression */
3787 /*-----------------------------------------------------------------*/
3789 optimizeGetHbit (ast * tree)
3792 /* if this is not a bit and */
3793 if (!IS_BITAND (tree))
3796 /* will look for tree of the form
3797 ( expr >> ((sizeof expr) -1) ) & 1 */
3798 if (!IS_AST_LIT_VALUE (tree->right))
3801 if (AST_LIT_VALUE (tree->right) != 1)
3804 if (!IS_RIGHT_OP (tree->left))
3807 if (!IS_AST_LIT_VALUE (tree->left->right))
3810 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3811 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3814 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3818 /*-----------------------------------------------------------------*/
3819 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3820 /*-----------------------------------------------------------------*/
3822 optimizeRRCRLC (ast * root)
3824 /* will look for trees of the form
3825 (?expr << 1) | (?expr >> 7) or
3826 (?expr >> 7) | (?expr << 1) will make that
3827 into a RLC : operation ..
3829 (?expr >> 1) | (?expr << 7) or
3830 (?expr << 7) | (?expr >> 1) will make that
3831 into a RRC operation
3832 note : by 7 I mean (number of bits required to hold the
3834 /* if the root operations is not a | operation the not */
3835 if (!IS_BITOR (root))
3838 /* I have to think of a better way to match patterns this sucks */
3839 /* that aside let start looking for the first case : I use a the
3840 negative check a lot to improve the efficiency */
3841 /* (?expr << 1) | (?expr >> 7) */
3842 if (IS_LEFT_OP (root->left) &&
3843 IS_RIGHT_OP (root->right))
3846 if (!SPEC_USIGN (TETYPE (root->left->left)))
3849 if (!IS_AST_LIT_VALUE (root->left->right) ||
3850 !IS_AST_LIT_VALUE (root->right->right))
3853 /* make sure it is the same expression */
3854 if (!isAstEqual (root->left->left,
3858 if (AST_LIT_VALUE (root->left->right) != 1)
3861 if (AST_LIT_VALUE (root->right->right) !=
3862 (getSize (TTYPE (root->left->left)) * 8 - 1))
3865 /* whew got the first case : create the AST */
3866 return newNode (RLC, root->left->left, NULL);
3870 /* check for second case */
3871 /* (?expr >> 7) | (?expr << 1) */
3872 if (IS_LEFT_OP (root->right) &&
3873 IS_RIGHT_OP (root->left))
3876 if (!SPEC_USIGN (TETYPE (root->left->left)))
3879 if (!IS_AST_LIT_VALUE (root->left->right) ||
3880 !IS_AST_LIT_VALUE (root->right->right))
3883 /* make sure it is the same symbol */
3884 if (!isAstEqual (root->left->left,
3888 if (AST_LIT_VALUE (root->right->right) != 1)
3891 if (AST_LIT_VALUE (root->left->right) !=
3892 (getSize (TTYPE (root->left->left)) * 8 - 1))
3895 /* whew got the first case : create the AST */
3896 return newNode (RLC, root->left->left, NULL);
3901 /* third case for RRC */
3902 /* (?symbol >> 1) | (?symbol << 7) */
3903 if (IS_LEFT_OP (root->right) &&
3904 IS_RIGHT_OP (root->left))
3907 if (!SPEC_USIGN (TETYPE (root->left->left)))
3910 if (!IS_AST_LIT_VALUE (root->left->right) ||
3911 !IS_AST_LIT_VALUE (root->right->right))
3914 /* make sure it is the same symbol */
3915 if (!isAstEqual (root->left->left,
3919 if (AST_LIT_VALUE (root->left->right) != 1)
3922 if (AST_LIT_VALUE (root->right->right) !=
3923 (getSize (TTYPE (root->left->left)) * 8 - 1))
3926 /* whew got the first case : create the AST */
3927 return newNode (RRC, root->left->left, NULL);
3931 /* fourth and last case for now */
3932 /* (?symbol << 7) | (?symbol >> 1) */
3933 if (IS_RIGHT_OP (root->right) &&
3934 IS_LEFT_OP (root->left))
3937 if (!SPEC_USIGN (TETYPE (root->left->left)))
3940 if (!IS_AST_LIT_VALUE (root->left->right) ||
3941 !IS_AST_LIT_VALUE (root->right->right))
3944 /* make sure it is the same symbol */
3945 if (!isAstEqual (root->left->left,
3949 if (AST_LIT_VALUE (root->right->right) != 1)
3952 if (AST_LIT_VALUE (root->left->right) !=
3953 (getSize (TTYPE (root->left->left)) * 8 - 1))
3956 /* whew got the first case : create the AST */
3957 return newNode (RRC, root->left->left, NULL);
3961 /* not found return root */
3965 /*-----------------------------------------------------------------*/
3966 /* optimizeCompare - otimizes compares for bit variables */
3967 /*-----------------------------------------------------------------*/
3969 optimizeCompare (ast * root)
3971 ast *optExpr = NULL;
3974 unsigned int litValue;
3976 /* if nothing then return nothing */
3980 /* if not a compare op then do leaves */
3981 if (!IS_COMPARE_OP (root))
3983 root->left = optimizeCompare (root->left);
3984 root->right = optimizeCompare (root->right);
3988 /* if left & right are the same then depending
3989 of the operation do */
3990 if (isAstEqual (root->left, root->right))
3992 switch (root->opval.op)
3997 optExpr = newAst_VALUE (constVal ("0"));
4002 optExpr = newAst_VALUE (constVal ("1"));
4006 return decorateType (optExpr);
4009 vleft = (root->left->type == EX_VALUE ?
4010 root->left->opval.val : NULL);
4012 vright = (root->right->type == EX_VALUE ?
4013 root->right->opval.val : NULL);
4015 /* if left is a BITVAR in BITSPACE */
4016 /* and right is a LITERAL then opt- */
4017 /* imize else do nothing */
4018 if (vleft && vright &&
4019 IS_BITVAR (vleft->etype) &&
4020 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4021 IS_LITERAL (vright->etype))
4024 /* if right side > 1 then comparison may never succeed */
4025 if ((litValue = (int) floatFromVal (vright)) > 1)
4027 werror (W_BAD_COMPARE);
4033 switch (root->opval.op)
4035 case '>': /* bit value greater than 1 cannot be */
4036 werror (W_BAD_COMPARE);
4040 case '<': /* bit value < 1 means 0 */
4042 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4045 case LE_OP: /* bit value <= 1 means no check */
4046 optExpr = newAst_VALUE (vright);
4049 case GE_OP: /* bit value >= 1 means only check for = */
4051 optExpr = newAst_VALUE (vleft);
4056 { /* literal is zero */
4057 switch (root->opval.op)
4059 case '<': /* bit value < 0 cannot be */
4060 werror (W_BAD_COMPARE);
4064 case '>': /* bit value > 0 means 1 */
4066 optExpr = newAst_VALUE (vleft);
4069 case LE_OP: /* bit value <= 0 means no check */
4070 case GE_OP: /* bit value >= 0 means no check */
4071 werror (W_BAD_COMPARE);
4075 case EQ_OP: /* bit == 0 means ! of bit */
4076 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4080 return decorateType (resolveSymbols (optExpr));
4081 } /* end-of-if of BITVAR */
4086 /*-----------------------------------------------------------------*/
4087 /* addSymToBlock : adds the symbol to the first block we find */
4088 /*-----------------------------------------------------------------*/
4090 addSymToBlock (symbol * sym, ast * tree)
4092 /* reached end of tree or a leaf */
4093 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4097 if (IS_AST_OP (tree) &&
4098 tree->opval.op == BLOCK)
4101 symbol *lsym = copySymbol (sym);
4103 lsym->next = AST_VALUES (tree, sym);
4104 AST_VALUES (tree, sym) = lsym;
4108 addSymToBlock (sym, tree->left);
4109 addSymToBlock (sym, tree->right);
4112 /*-----------------------------------------------------------------*/
4113 /* processRegParms - do processing for register parameters */
4114 /*-----------------------------------------------------------------*/
4116 processRegParms (value * args, ast * body)
4120 if (IS_REGPARM (args->etype))
4121 addSymToBlock (args->sym, body);
4126 /*-----------------------------------------------------------------*/
4127 /* resetParmKey - resets the operandkeys for the symbols */
4128 /*-----------------------------------------------------------------*/
4129 DEFSETFUNC (resetParmKey)
4140 /*-----------------------------------------------------------------*/
4141 /* createFunction - This is the key node that calls the iCode for */
4142 /* generating the code for a function. Note code */
4143 /* is generated function by function, later when */
4144 /* add inter-procedural analysis this will change */
4145 /*-----------------------------------------------------------------*/
4147 createFunction (symbol * name, ast * body)
4153 iCode *piCode = NULL;
4155 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4156 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4158 /* if check function return 0 then some problem */
4159 if (checkFunction (name, NULL) == 0)
4162 /* create a dummy block if none exists */
4164 body = newNode (BLOCK, NULL, NULL);
4168 /* check if the function name already in the symbol table */
4169 if ((csym = findSym (SymbolTab, NULL, name->name)))
4172 /* special case for compiler defined functions
4173 we need to add the name to the publics list : this
4174 actually means we are now compiling the compiler
4178 addSet (&publics, name);
4184 allocVariables (name);
4186 name->lastLine = yylineno;
4189 /* set the stack pointer */
4190 /* PENDING: check this for the mcs51 */
4191 stackPtr = -port->stack.direction * port->stack.call_overhead;
4192 if (IFFUNC_ISISR (name->type))
4193 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4194 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4195 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4197 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4199 fetype = getSpec (name->type); /* get the specifier for the function */
4200 /* if this is a reentrant function then */
4201 if (IFFUNC_ISREENT (name->type))
4204 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4206 /* do processing for parameters that are passed in registers */
4207 processRegParms (FUNC_ARGS(name->type), body);
4209 /* set the stack pointer */
4213 /* allocate & autoinit the block variables */
4214 processBlockVars (body, &stack, ALLOCATE);
4216 /* save the stack information */
4217 if (options.useXstack)
4218 name->xstack = SPEC_STAK (fetype) = stack;
4220 name->stack = SPEC_STAK (fetype) = stack;
4222 /* name needs to be mangled */
4223 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4225 body = resolveSymbols (body); /* resolve the symbols */
4226 body = decorateType (body); /* propagateType & do semantic checks */
4228 ex = newAst_VALUE (symbolVal (name)); /* create name */
4229 ex = newNode (FUNCTION, ex, body);
4230 ex->values.args = FUNC_ARGS(name->type);
4232 if (options.dump_tree) PA(ex);
4235 werror (E_FUNC_NO_CODE, name->name);
4239 /* create the node & generate intermediate code */
4241 codeOutFile = code->oFile;
4242 piCode = iCodeFromAst (ex);
4246 werror (E_FUNC_NO_CODE, name->name);
4250 eBBlockFromiCode (piCode);
4252 /* if there are any statics then do them */
4255 GcurMemmap = statsg;
4256 codeOutFile = statsg->oFile;
4257 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4263 /* dealloc the block variables */
4264 processBlockVars (body, &stack, DEALLOCATE);
4265 /* deallocate paramaters */
4266 deallocParms (FUNC_ARGS(name->type));
4268 if (IFFUNC_ISREENT (name->type))
4271 /* we are done freeup memory & cleanup */
4273 if (port->reset_labelKey) labelKey = 1;
4275 FUNC_HASBODY(name->type) = 1;
4276 addSet (&operKeyReset, name);
4277 applyToSet (operKeyReset, resetParmKey);
4280 cdbStructBlock (1, cdbFile);
4282 cleanUpLevel (LabelTab, 0);
4283 cleanUpBlock (StructTab, 1);
4284 cleanUpBlock (TypedefTab, 1);
4286 xstack->syms = NULL;
4287 istack->syms = NULL;
4292 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4293 /*-----------------------------------------------------------------*/
4294 /* ast_print : prints the ast (for debugging purposes) */
4295 /*-----------------------------------------------------------------*/
4297 void ast_print (ast * tree, FILE *outfile, int indent)
4302 /* can print only decorated trees */
4303 if (!tree->decorated) return;
4305 /* if any child is an error | this one is an error do nothing */
4306 if (tree->isError ||
4307 (tree->left && tree->left->isError) ||
4308 (tree->right && tree->right->isError)) {
4309 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4313 /* print the line */
4314 /* if not block & function */
4315 if (tree->type == EX_OP &&
4316 (tree->opval.op != FUNCTION &&
4317 tree->opval.op != BLOCK &&
4318 tree->opval.op != NULLOP)) {
4321 if (tree->opval.op == FUNCTION) {
4323 value *args=FUNC_ARGS(tree->left->opval.val->type);
4324 fprintf(outfile,"FUNCTION (%s=%p) type (",
4325 tree->left->opval.val->name, tree);
4326 printTypeChain (tree->ftype,outfile);
4327 fprintf(outfile,") args (");
4330 fprintf (outfile, ", ");
4332 printTypeChain (args ? args->type : NULL, outfile);
4334 args= args ? args->next : NULL;
4336 fprintf(outfile,")\n");
4337 ast_print(tree->left,outfile,indent);
4338 ast_print(tree->right,outfile,indent);
4341 if (tree->opval.op == BLOCK) {
4342 symbol *decls = tree->values.sym;
4343 INDENT(indent,outfile);
4344 fprintf(outfile,"{\n");
4346 INDENT(indent+2,outfile);
4347 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4348 decls->name, decls);
4349 printTypeChain(decls->type,outfile);
4350 fprintf(outfile,")\n");
4352 decls = decls->next;
4354 ast_print(tree->right,outfile,indent+2);
4355 INDENT(indent,outfile);
4356 fprintf(outfile,"}\n");
4359 if (tree->opval.op == NULLOP) {
4360 fprintf(outfile,"\n");
4361 ast_print(tree->left,outfile,indent);
4362 fprintf(outfile,"\n");
4363 ast_print(tree->right,outfile,indent);
4366 INDENT(indent,outfile);
4368 /*------------------------------------------------------------------*/
4369 /*----------------------------*/
4370 /* leaf has been reached */
4371 /*----------------------------*/
4372 /* if this is of type value */
4373 /* just get the type */
4374 if (tree->type == EX_VALUE) {
4376 if (IS_LITERAL (tree->opval.val->etype)) {
4377 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4378 (int) floatFromVal(tree->opval.val),
4379 (int) floatFromVal(tree->opval.val),
4380 floatFromVal(tree->opval.val));
4381 } else if (tree->opval.val->sym) {
4382 /* if the undefined flag is set then give error message */
4383 if (tree->opval.val->sym->undefined) {
4384 fprintf(outfile,"UNDEFINED SYMBOL ");
4386 fprintf(outfile,"SYMBOL ");
4388 fprintf(outfile,"(%s=%p)",
4389 tree->opval.val->sym->name,tree);
4392 fprintf(outfile," type (");
4393 printTypeChain(tree->ftype,outfile);
4394 fprintf(outfile,")\n");
4396 fprintf(outfile,"\n");
4401 /* if type link for the case of cast */
4402 if (tree->type == EX_LINK) {
4403 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4404 printTypeChain(tree->opval.lnk,outfile);
4405 fprintf(outfile,")\n");
4410 /* depending on type of operator do */
4412 switch (tree->opval.op) {
4413 /*------------------------------------------------------------------*/
4414 /*----------------------------*/
4416 /*----------------------------*/
4418 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4419 printTypeChain(tree->ftype,outfile);
4420 fprintf(outfile,")\n");
4421 ast_print(tree->left,outfile,indent+2);
4422 ast_print(tree->right,outfile,indent+2);
4425 /*------------------------------------------------------------------*/
4426 /*----------------------------*/
4428 /*----------------------------*/
4430 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4431 printTypeChain(tree->ftype,outfile);
4432 fprintf(outfile,")\n");
4433 ast_print(tree->left,outfile,indent+2);
4434 ast_print(tree->right,outfile,indent+2);
4437 /*------------------------------------------------------------------*/
4438 /*----------------------------*/
4439 /* struct/union pointer */
4440 /*----------------------------*/
4442 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4443 printTypeChain(tree->ftype,outfile);
4444 fprintf(outfile,")\n");
4445 ast_print(tree->left,outfile,indent+2);
4446 ast_print(tree->right,outfile,indent+2);
4449 /*------------------------------------------------------------------*/
4450 /*----------------------------*/
4451 /* ++/-- operation */
4452 /*----------------------------*/
4453 case INC_OP: /* incerement operator unary so left only */
4454 fprintf(outfile,"INC_OP (%p) type (",tree);
4455 printTypeChain(tree->ftype,outfile);
4456 fprintf(outfile,")\n");
4457 ast_print(tree->left,outfile,indent+2);
4461 fprintf(outfile,"DEC_OP (%p) type (",tree);
4462 printTypeChain(tree->ftype,outfile);
4463 fprintf(outfile,")\n");
4464 ast_print(tree->left,outfile,indent+2);
4467 /*------------------------------------------------------------------*/
4468 /*----------------------------*/
4470 /*----------------------------*/
4473 fprintf(outfile,"& (%p) type (",tree);
4474 printTypeChain(tree->ftype,outfile);
4475 fprintf(outfile,")\n");
4476 ast_print(tree->left,outfile,indent+2);
4477 ast_print(tree->right,outfile,indent+2);
4479 fprintf(outfile,"ADDRESS_OF (%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 /*----------------------------*/
4488 /*----------------------------*/
4490 fprintf(outfile,"OR (%p) type (",tree);
4491 printTypeChain(tree->ftype,outfile);
4492 fprintf(outfile,")\n");
4493 ast_print(tree->left,outfile,indent+2);
4494 ast_print(tree->right,outfile,indent+2);
4496 /*------------------------------------------------------------------*/
4497 /*----------------------------*/
4499 /*----------------------------*/
4501 fprintf(outfile,"XOR (%p) type (",tree);
4502 printTypeChain(tree->ftype,outfile);
4503 fprintf(outfile,")\n");
4504 ast_print(tree->left,outfile,indent+2);
4505 ast_print(tree->right,outfile,indent+2);
4508 /*------------------------------------------------------------------*/
4509 /*----------------------------*/
4511 /*----------------------------*/
4513 fprintf(outfile,"DIV (%p) type (",tree);
4514 printTypeChain(tree->ftype,outfile);
4515 fprintf(outfile,")\n");
4516 ast_print(tree->left,outfile,indent+2);
4517 ast_print(tree->right,outfile,indent+2);
4519 /*------------------------------------------------------------------*/
4520 /*----------------------------*/
4522 /*----------------------------*/
4524 fprintf(outfile,"MOD (%p) type (",tree);
4525 printTypeChain(tree->ftype,outfile);
4526 fprintf(outfile,")\n");
4527 ast_print(tree->left,outfile,indent+2);
4528 ast_print(tree->right,outfile,indent+2);
4531 /*------------------------------------------------------------------*/
4532 /*----------------------------*/
4533 /* address dereference */
4534 /*----------------------------*/
4535 case '*': /* can be unary : if right is null then unary operation */
4537 fprintf(outfile,"DEREF (%p) type (",tree);
4538 printTypeChain(tree->ftype,outfile);
4539 fprintf(outfile,")\n");
4540 ast_print(tree->left,outfile,indent+2);
4543 /*------------------------------------------------------------------*/
4544 /*----------------------------*/
4545 /* multiplication */
4546 /*----------------------------*/
4547 fprintf(outfile,"MULT (%p) type (",tree);
4548 printTypeChain(tree->ftype,outfile);
4549 fprintf(outfile,")\n");
4550 ast_print(tree->left,outfile,indent+2);
4551 ast_print(tree->right,outfile,indent+2);
4555 /*------------------------------------------------------------------*/
4556 /*----------------------------*/
4557 /* unary '+' operator */
4558 /*----------------------------*/
4562 fprintf(outfile,"UPLUS (%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,"ADD (%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 /*----------------------------*/
4582 case '-': /* can be unary */
4584 fprintf(outfile,"UMINUS (%p) type (",tree);
4585 printTypeChain(tree->ftype,outfile);
4586 fprintf(outfile,")\n");
4587 ast_print(tree->left,outfile,indent+2);
4589 /*------------------------------------------------------------------*/
4590 /*----------------------------*/
4592 /*----------------------------*/
4593 fprintf(outfile,"SUB (%p) type (",tree);
4594 printTypeChain(tree->ftype,outfile);
4595 fprintf(outfile,")\n");
4596 ast_print(tree->left,outfile,indent+2);
4597 ast_print(tree->right,outfile,indent+2);
4600 /*------------------------------------------------------------------*/
4601 /*----------------------------*/
4603 /*----------------------------*/
4605 fprintf(outfile,"COMPL (%p) type (",tree);
4606 printTypeChain(tree->ftype,outfile);
4607 fprintf(outfile,")\n");
4608 ast_print(tree->left,outfile,indent+2);
4610 /*------------------------------------------------------------------*/
4611 /*----------------------------*/
4613 /*----------------------------*/
4615 fprintf(outfile,"NOT (%p) type (",tree);
4616 printTypeChain(tree->ftype,outfile);
4617 fprintf(outfile,")\n");
4618 ast_print(tree->left,outfile,indent+2);
4620 /*------------------------------------------------------------------*/
4621 /*----------------------------*/
4623 /*----------------------------*/
4625 fprintf(outfile,"RRC (%p) type (",tree);
4626 printTypeChain(tree->ftype,outfile);
4627 fprintf(outfile,")\n");
4628 ast_print(tree->left,outfile,indent+2);
4632 fprintf(outfile,"RLC (%p) type (",tree);
4633 printTypeChain(tree->ftype,outfile);
4634 fprintf(outfile,")\n");
4635 ast_print(tree->left,outfile,indent+2);
4638 fprintf(outfile,"GETHBIT (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+2);
4644 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4645 printTypeChain(tree->ftype,outfile);
4646 fprintf(outfile,")\n");
4647 ast_print(tree->left,outfile,indent+2);
4648 ast_print(tree->right,outfile,indent+2);
4651 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4652 printTypeChain(tree->ftype,outfile);
4653 fprintf(outfile,")\n");
4654 ast_print(tree->left,outfile,indent+2);
4655 ast_print(tree->right,outfile,indent+2);
4657 /*------------------------------------------------------------------*/
4658 /*----------------------------*/
4660 /*----------------------------*/
4661 case CAST: /* change the type */
4662 fprintf(outfile,"CAST (%p) from type (",tree);
4663 printTypeChain(tree->right->ftype,outfile);
4664 fprintf(outfile,") to type (");
4665 printTypeChain(tree->ftype,outfile);
4666 fprintf(outfile,")\n");
4667 ast_print(tree->right,outfile,indent+2);
4671 fprintf(outfile,"ANDAND (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+2);
4675 ast_print(tree->right,outfile,indent+2);
4678 fprintf(outfile,"OROR (%p) type (",tree);
4679 printTypeChain(tree->ftype,outfile);
4680 fprintf(outfile,")\n");
4681 ast_print(tree->left,outfile,indent+2);
4682 ast_print(tree->right,outfile,indent+2);
4685 /*------------------------------------------------------------------*/
4686 /*----------------------------*/
4687 /* comparison operators */
4688 /*----------------------------*/
4690 fprintf(outfile,"GT(>) (%p) type (",tree);
4691 printTypeChain(tree->ftype,outfile);
4692 fprintf(outfile,")\n");
4693 ast_print(tree->left,outfile,indent+2);
4694 ast_print(tree->right,outfile,indent+2);
4697 fprintf(outfile,"LT(<) (%p) type (",tree);
4698 printTypeChain(tree->ftype,outfile);
4699 fprintf(outfile,")\n");
4700 ast_print(tree->left,outfile,indent+2);
4701 ast_print(tree->right,outfile,indent+2);
4704 fprintf(outfile,"LE(<=) (%p) type (",tree);
4705 printTypeChain(tree->ftype,outfile);
4706 fprintf(outfile,")\n");
4707 ast_print(tree->left,outfile,indent+2);
4708 ast_print(tree->right,outfile,indent+2);
4711 fprintf(outfile,"GE(>=) (%p) type (",tree);
4712 printTypeChain(tree->ftype,outfile);
4713 fprintf(outfile,")\n");
4714 ast_print(tree->left,outfile,indent+2);
4715 ast_print(tree->right,outfile,indent+2);
4718 fprintf(outfile,"EQ(==) (%p) type (",tree);
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->left,outfile,indent+2);
4722 ast_print(tree->right,outfile,indent+2);
4725 fprintf(outfile,"NE(!=) (%p) type (",tree);
4726 printTypeChain(tree->ftype,outfile);
4727 fprintf(outfile,")\n");
4728 ast_print(tree->left,outfile,indent+2);
4729 ast_print(tree->right,outfile,indent+2);
4730 /*------------------------------------------------------------------*/
4731 /*----------------------------*/
4733 /*----------------------------*/
4734 case SIZEOF: /* evaluate wihout code generation */
4735 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4738 /*------------------------------------------------------------------*/
4739 /*----------------------------*/
4740 /* conditional operator '?' */
4741 /*----------------------------*/
4743 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4744 printTypeChain(tree->ftype,outfile);
4745 fprintf(outfile,")\n");
4746 ast_print(tree->left,outfile,indent+2);
4747 ast_print(tree->right,outfile,indent+2);
4751 fprintf(outfile,"COLON(:) (%p) type (",tree);
4752 printTypeChain(tree->ftype,outfile);
4753 fprintf(outfile,")\n");
4754 ast_print(tree->left,outfile,indent+2);
4755 ast_print(tree->right,outfile,indent+2);
4758 /*------------------------------------------------------------------*/
4759 /*----------------------------*/
4760 /* assignment operators */
4761 /*----------------------------*/
4763 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+2);
4767 ast_print(tree->right,outfile,indent+2);
4770 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4771 printTypeChain(tree->ftype,outfile);
4772 fprintf(outfile,")\n");
4773 ast_print(tree->left,outfile,indent+2);
4774 ast_print(tree->right,outfile,indent+2);
4777 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4778 printTypeChain(tree->ftype,outfile);
4779 fprintf(outfile,")\n");
4780 ast_print(tree->left,outfile,indent+2);
4781 ast_print(tree->right,outfile,indent+2);
4784 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4785 printTypeChain(tree->ftype,outfile);
4786 fprintf(outfile,")\n");
4787 ast_print(tree->left,outfile,indent+2);
4788 ast_print(tree->right,outfile,indent+2);
4791 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4792 printTypeChain(tree->ftype,outfile);
4793 fprintf(outfile,")\n");
4794 ast_print(tree->left,outfile,indent+2);
4795 ast_print(tree->right,outfile,indent+2);
4798 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4799 printTypeChain(tree->ftype,outfile);
4800 fprintf(outfile,")\n");
4801 ast_print(tree->left,outfile,indent+2);
4802 ast_print(tree->right,outfile,indent+2);
4805 fprintf(outfile,"LSHFTASS(*=) (%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 /*----------------------------*/
4814 /*----------------------------*/
4816 fprintf(outfile,"SUBASS(-=) (%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 /*----------------------------*/
4825 /*----------------------------*/
4827 fprintf(outfile,"ADDASS(+=) (%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 /*----------------------------*/
4835 /* straight assignemnt */
4836 /*----------------------------*/
4838 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4839 printTypeChain(tree->ftype,outfile);
4840 fprintf(outfile,")\n");
4841 ast_print(tree->left,outfile,indent+2);
4842 ast_print(tree->right,outfile,indent+2);
4844 /*------------------------------------------------------------------*/
4845 /*----------------------------*/
4846 /* comma operator */
4847 /*----------------------------*/
4849 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4850 printTypeChain(tree->ftype,outfile);
4851 fprintf(outfile,")\n");
4852 ast_print(tree->left,outfile,indent+2);
4853 ast_print(tree->right,outfile,indent+2);
4855 /*------------------------------------------------------------------*/
4856 /*----------------------------*/
4858 /*----------------------------*/
4861 fprintf(outfile,"CALL (%p) type (",tree);
4862 printTypeChain(tree->ftype,outfile);
4863 fprintf(outfile,")\n");
4864 ast_print(tree->left,outfile,indent+2);
4865 ast_print(tree->right,outfile,indent+2);
4868 fprintf(outfile,"PARMS\n");
4869 ast_print(tree->left,outfile,indent+2);
4870 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4871 ast_print(tree->right,outfile,indent+2);
4874 /*------------------------------------------------------------------*/
4875 /*----------------------------*/
4876 /* return statement */
4877 /*----------------------------*/
4879 fprintf(outfile,"RETURN (%p) type (",tree);
4880 printTypeChain(tree->right->ftype,outfile);
4881 fprintf(outfile,")\n");
4882 ast_print(tree->right,outfile,indent+2);
4884 /*------------------------------------------------------------------*/
4885 /*----------------------------*/
4886 /* label statement */
4887 /*----------------------------*/
4889 fprintf(outfile,"LABEL (%p)\n",tree);
4890 ast_print(tree->left,outfile,indent+2);
4891 ast_print(tree->right,outfile,indent);
4893 /*------------------------------------------------------------------*/
4894 /*----------------------------*/
4895 /* switch statement */
4896 /*----------------------------*/
4900 fprintf(outfile,"SWITCH (%p) ",tree);
4901 ast_print(tree->left,outfile,0);
4902 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4903 INDENT(indent+2,outfile);
4904 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4905 (int) floatFromVal(val),
4906 tree->values.switchVals.swNum,
4907 (int) floatFromVal(val));
4909 ast_print(tree->right,outfile,indent);
4912 /*------------------------------------------------------------------*/
4913 /*----------------------------*/
4915 /*----------------------------*/
4917 fprintf(outfile,"IF (%p) \n",tree);
4918 ast_print(tree->left,outfile,indent+2);
4919 if (tree->trueLabel) {
4920 INDENT(indent,outfile);
4921 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4923 if (tree->falseLabel) {
4924 INDENT(indent,outfile);
4925 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4927 ast_print(tree->right,outfile,indent+2);
4929 /*------------------------------------------------------------------*/
4930 /*----------------------------*/
4932 /*----------------------------*/
4934 fprintf(outfile,"FOR (%p) \n",tree);
4935 if (AST_FOR( tree, initExpr)) {
4936 INDENT(indent+2,outfile);
4937 fprintf(outfile,"INIT EXPR ");
4938 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4940 if (AST_FOR( tree, condExpr)) {
4941 INDENT(indent+2,outfile);
4942 fprintf(outfile,"COND EXPR ");
4943 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4945 if (AST_FOR( tree, loopExpr)) {
4946 INDENT(indent+2,outfile);
4947 fprintf(outfile,"LOOP EXPR ");
4948 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4950 fprintf(outfile,"FOR LOOP BODY \n");
4951 ast_print(tree->left,outfile,indent+2);
4960 ast_print(t,stdout,0);