1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
73 newAst_ (unsigned type)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
90 newAst_VALUE (value * val)
92 ast *ex = newAst_ (EX_VALUE);
98 newAst_OP (unsigned op)
100 ast *ex = newAst_ (EX_OP);
106 newAst_LINK (sym_link * val)
108 ast *ex = newAst_ (EX_LINK);
114 newAst_STMNT (unsigned val)
116 ast *ex = newAst_ (EX_STMNT);
117 ex->opval.stmnt = val;
121 /*-----------------------------------------------------------------*/
122 /* newNode - creates a new node */
123 /*-----------------------------------------------------------------*/
125 newNode (long op, ast * left, ast * right)
136 /*-----------------------------------------------------------------*/
137 /* newIfxNode - creates a new Ifx Node */
138 /*-----------------------------------------------------------------*/
140 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
144 /* if this is a literal then we already know the result */
145 if (condAst->etype && IS_LITERAL (condAst->etype))
147 /* then depending on the expression value */
148 if (floatFromVal (condAst->opval.val))
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (trueLabel)),
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (falseLabel)),
159 ifxNode = newNode (IFX, condAst, NULL);
160 ifxNode->trueLabel = trueLabel;
161 ifxNode->falseLabel = falseLabel;
167 /*-----------------------------------------------------------------*/
168 /* copyAstValues - copies value portion of ast if needed */
169 /*-----------------------------------------------------------------*/
171 copyAstValues (ast * dest, ast * src)
173 switch (src->opval.op)
176 dest->values.sym = copySymbolChain (src->values.sym);
180 dest->values.switchVals.swVals =
181 copyValue (src->values.switchVals.swVals);
182 dest->values.switchVals.swDefault =
183 src->values.switchVals.swDefault;
184 dest->values.switchVals.swNum =
185 src->values.switchVals.swNum;
189 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
190 strcpy (dest->values.inlineasm, src->values.inlineasm);
194 dest->values.constlist = copyLiteralList(src->values.constlist);
198 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
199 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
200 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
201 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
202 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
203 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
204 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
209 /*-----------------------------------------------------------------*/
210 /* copyAst - makes a copy of a given astession */
211 /*-----------------------------------------------------------------*/
220 dest = Safe_alloc ( sizeof (ast));
222 dest->type = src->type;
223 dest->lineno = src->lineno;
224 dest->level = src->level;
225 dest->funcName = src->funcName;
228 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
230 /* if this is a leaf */
232 if (src->type == EX_VALUE)
234 dest->opval.val = copyValue (src->opval.val);
239 if (src->type == EX_LINK)
241 dest->opval.lnk = copyLinkChain (src->opval.lnk);
245 dest->opval.op = src->opval.op;
247 /* if this is a node that has special values */
248 copyAstValues (dest, src);
250 dest->trueLabel = copySymbol (src->trueLabel);
251 dest->falseLabel = copySymbol (src->falseLabel);
252 dest->left = copyAst (src->left);
253 dest->right = copyAst (src->right);
259 /*-----------------------------------------------------------------*/
260 /* hasSEFcalls - returns TRUE if tree has a function call */
261 /*-----------------------------------------------------------------*/
263 hasSEFcalls (ast * tree)
268 if (tree->type == EX_OP &&
269 (tree->opval.op == CALL ||
270 tree->opval.op == PCALL ||
271 tree->opval.op == '=' ||
272 tree->opval.op == INC_OP ||
273 tree->opval.op == DEC_OP))
276 return (hasSEFcalls (tree->left) |
277 hasSEFcalls (tree->right));
280 /*-----------------------------------------------------------------*/
281 /* isAstEqual - compares two asts & returns 1 if they are equal */
282 /*-----------------------------------------------------------------*/
284 isAstEqual (ast * t1, ast * t2)
293 if (t1->type != t2->type)
299 if (t1->opval.op != t2->opval.op)
301 return (isAstEqual (t1->left, t2->left) &&
302 isAstEqual (t1->right, t2->right));
306 if (t1->opval.val->sym)
308 if (!t2->opval.val->sym)
311 return isSymbolEqual (t1->opval.val->sym,
316 if (t2->opval.val->sym)
319 return (floatFromVal (t1->opval.val) ==
320 floatFromVal (t2->opval.val));
324 /* only compare these two types */
332 /*-----------------------------------------------------------------*/
333 /* resolveSymbols - resolve symbols from the symbol table */
334 /*-----------------------------------------------------------------*/
336 resolveSymbols (ast * tree)
338 /* walk the entire tree and check for values */
339 /* with symbols if we find one then replace */
340 /* symbol with that from the symbol table */
346 /* if not block & function */
347 if (tree->type == EX_OP &&
348 (tree->opval.op != FUNCTION &&
349 tree->opval.op != BLOCK &&
350 tree->opval.op != NULLOP))
352 filename = tree->filename;
353 lineno = tree->lineno;
356 /* make sure we resolve the true & false labels for ifx */
357 if (tree->type == EX_OP && tree->opval.op == IFX)
363 if ((csym = findSym (LabelTab, tree->trueLabel,
364 tree->trueLabel->name)))
365 tree->trueLabel = csym;
367 werror (E_LABEL_UNDEF, tree->trueLabel->name);
370 if (tree->falseLabel)
372 if ((csym = findSym (LabelTab,
374 tree->falseLabel->name)))
375 tree->falseLabel = csym;
377 werror (E_LABEL_UNDEF, tree->falseLabel->name);
382 /* if this is a label resolve it from the labelTab */
383 if (IS_AST_VALUE (tree) &&
384 tree->opval.val->sym &&
385 tree->opval.val->sym->islbl)
388 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
389 tree->opval.val->sym->name);
392 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
394 tree->opval.val->sym = csym;
396 goto resolveChildren;
399 /* do only for leafs */
400 if (IS_AST_VALUE (tree) &&
401 tree->opval.val->sym &&
402 !tree->opval.val->sym->implicit)
405 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
407 /* if found in the symbol table & they r not the same */
408 if (csym && tree->opval.val->sym != csym)
410 tree->opval.val->sym = csym;
411 tree->opval.val->type = csym->type;
412 tree->opval.val->etype = csym->etype;
415 /* if not found in the symbol table */
416 /* mark it as undefined assume it is */
417 /* an integer in data space */
418 if (!csym && !tree->opval.val->sym->implicit)
421 /* if this is a function name then */
422 /* mark it as returning an int */
425 tree->opval.val->sym->type = newLink ();
426 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
427 tree->opval.val->sym->type->next =
428 tree->opval.val->sym->etype = newIntLink ();
429 tree->opval.val->etype = tree->opval.val->etype;
430 tree->opval.val->type = tree->opval.val->sym->type;
431 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
432 allocVariables (tree->opval.val->sym);
436 tree->opval.val->sym->undefined = 1;
437 tree->opval.val->type =
438 tree->opval.val->etype = newIntLink ();
439 tree->opval.val->sym->type =
440 tree->opval.val->sym->etype = newIntLink ();
446 resolveSymbols (tree->left);
447 resolveSymbols (tree->right);
452 /*-----------------------------------------------------------------*/
453 /* setAstLineno - walks a ast tree & sets the line number */
454 /*-----------------------------------------------------------------*/
456 setAstLineno (ast * tree, int lineno)
461 tree->lineno = lineno;
462 setAstLineno (tree->left, lineno);
463 setAstLineno (tree->right, lineno);
467 /*-----------------------------------------------------------------*/
468 /* funcOfType :- function of type with name */
469 /*-----------------------------------------------------------------*/
471 funcOfType (char *name, sym_link * type, sym_link * argType,
475 /* create the symbol */
476 sym = newSymbol (name, 0);
478 /* setup return value */
479 sym->type = newLink ();
480 DCL_TYPE (sym->type) = FUNCTION;
481 sym->type->next = copyLinkChain (type);
482 sym->etype = getSpec (sym->type);
483 FUNC_ISREENT(sym->type) = rent;
485 /* if arguments required */
489 args = FUNC_ARGS(sym->type) = newValue ();
493 args->type = copyLinkChain (argType);
494 args->etype = getSpec (args->type);
495 SPEC_EXTR(args->etype)=1;
498 args = args->next = newValue ();
505 allocVariables (sym);
510 /*-----------------------------------------------------------------*/
511 /* funcOfTypeVarg :- function of type with name and argtype */
512 /*-----------------------------------------------------------------*/
514 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
519 /* create the symbol */
520 sym = newSymbol (name, 0);
522 /* setup return value */
523 sym->type = newLink ();
524 DCL_TYPE (sym->type) = FUNCTION;
525 sym->type->next = typeFromStr(rtype);
526 sym->etype = getSpec (sym->type);
528 /* if arguments required */
531 args = FUNC_ARGS(sym->type) = newValue ();
533 for ( i = 0 ; i < nArgs ; i++ ) {
534 args->type = typeFromStr(atypes[i]);
535 args->etype = getSpec (args->type);
536 SPEC_EXTR(args->etype)=1;
537 if ((i + 1) == nArgs) break;
538 args = args->next = newValue ();
545 allocVariables (sym);
550 /*-----------------------------------------------------------------*/
551 /* reverseParms - will reverse a parameter tree */
552 /*-----------------------------------------------------------------*/
554 reverseParms (ast * ptree)
560 /* top down if we find a nonParm tree then quit */
561 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
564 ptree->left = ptree->right;
565 ptree->right = ttree;
566 reverseParms (ptree->left);
567 reverseParms (ptree->right);
573 /*-----------------------------------------------------------------*/
574 /* processParms - makes sure the parameters are okay and do some */
575 /* processing with them */
576 /*-----------------------------------------------------------------*/
578 processParms (ast * func,
581 int *parmNumber, // unused, although updated
584 /* if none of them exist */
585 if (!defParm && !actParm)
589 if (getenv("DEBUG_SANITY")) {
590 fprintf (stderr, "processParms: %s ", defParm->name);
592 /* make sure the type is complete and sane */
593 checkTypeSanity(defParm->etype, defParm->name);
596 /* if the function is being called via a pointer & */
597 /* it has not been defined a reentrant then we cannot */
598 /* have parameters */
599 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
601 werror (W_NONRENT_ARGS);
605 /* if defined parameters ended but actual parameters */
606 /* exist and this is not defined as a variable arg */
607 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
609 werror (E_TOO_MANY_PARMS);
613 /* if defined parameters present but no actual parameters */
614 if (defParm && !actParm)
616 werror (E_TOO_FEW_PARMS);
620 if (IS_VOID(actParm->ftype)) {
621 werror (E_VOID_VALUE_USED);
625 /* If this is a varargs function... */
626 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
631 if (IS_CAST_OP (actParm)
632 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
634 /* Parameter was explicitly typecast; don't touch it. */
638 ftype = actParm->ftype;
640 /* If it's a small integer, upcast to int. */
641 if (IS_INTEGRAL (ftype)
642 && (getSize (ftype) < (unsigned) INTSIZE))
644 newType = newAst_LINK(INTTYPE);
647 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
649 newType = newAst_LINK (copyLinkChain(ftype));
650 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
653 if (IS_AGGREGATE (ftype))
655 newType = newAst_LINK (copyLinkChain (ftype));
656 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
660 /* cast required; change this op to a cast. */
661 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
663 actParm->type = EX_OP;
664 actParm->opval.op = CAST;
665 actParm->left = newType;
666 actParm->right = parmCopy;
667 decorateType (actParm);
669 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
671 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
672 processParms (func, NULL, actParm->right, parmNumber, rightmost));
677 /* if defined parameters ended but actual has not & */
679 if (!defParm && actParm &&
680 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
683 resolveSymbols (actParm);
684 /* if this is a PARAM node then match left & right */
685 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
687 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
688 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
692 /* If we have found a value node by following only right-hand links,
693 * then we know that there are no more values after us.
695 * Therefore, if there are more defined parameters, the caller didn't
698 if (rightmost && defParm->next)
700 werror (E_TOO_FEW_PARMS);
705 /* the parameter type must be at least castable */
706 if (compareType (defParm->type, actParm->ftype) == 0) {
707 werror (E_INCOMPAT_TYPES);
708 printFromToType (actParm->ftype, defParm->type);
712 /* if the parameter is castable then add the cast */
713 if (compareType (defParm->type, actParm->ftype) < 0)
715 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
717 /* now change the current one to a cast */
718 actParm->type = EX_OP;
719 actParm->opval.op = CAST;
720 actParm->left = newAst_LINK (defParm->type);
721 actParm->right = pTree;
722 actParm->etype = defParm->etype;
723 actParm->ftype = defParm->type;
724 actParm->decorated=0; /* force typechecking */
725 decorateType (actParm);
728 /* make a copy and change the regparm type to the defined parm */
729 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
730 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
734 /*-----------------------------------------------------------------*/
735 /* createIvalType - generates ival for basic types */
736 /*-----------------------------------------------------------------*/
738 createIvalType (ast * sym, sym_link * type, initList * ilist)
742 /* if initList is deep */
743 if (ilist->type == INIT_DEEP)
744 ilist = ilist->init.deep;
746 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
747 return decorateType (newNode ('=', sym, iExpr));
750 /*-----------------------------------------------------------------*/
751 /* createIvalStruct - generates initial value for structures */
752 /*-----------------------------------------------------------------*/
754 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
761 sflds = SPEC_STRUCT (type)->fields;
762 if (ilist->type != INIT_DEEP)
764 werror (E_INIT_STRUCT, "");
768 iloop = ilist->init.deep;
770 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
772 /* if we have come to end */
776 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
777 lAst = decorateType (resolveSymbols (lAst));
778 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
782 werror (W_EXCESS_INITIALIZERS, "struct",
783 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
790 /*-----------------------------------------------------------------*/
791 /* createIvalArray - generates code for array initialization */
792 /*-----------------------------------------------------------------*/
794 createIvalArray (ast * sym, sym_link * type, initList * ilist)
798 int lcnt = 0, size = 0;
799 literalList *literalL;
801 /* take care of the special case */
802 /* array of characters can be init */
804 if (IS_CHAR (type->next))
805 if ((rast = createIvalCharPtr (sym,
807 decorateType (resolveSymbols (list2expr (ilist))))))
809 return decorateType (resolveSymbols (rast));
811 /* not the special case */
812 if (ilist->type != INIT_DEEP)
814 werror (E_INIT_STRUCT, "");
818 iloop = ilist->init.deep;
819 lcnt = DCL_ELEM (type);
821 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
825 aSym = decorateType (resolveSymbols(sym));
827 rast = newNode(ARRAYINIT, aSym, NULL);
828 rast->values.constlist = literalL;
830 // Make sure size is set to length of initializer list.
837 if (lcnt && size > lcnt)
839 // Array size was specified, and we have more initializers than needed.
840 char *name=sym->opval.val->sym->name;
841 int lineno=sym->opval.val->sym->lineDef;
843 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
852 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
853 aSym = decorateType (resolveSymbols (aSym));
854 rast = createIval (aSym, type->next, iloop, rast);
855 iloop = (iloop ? iloop->next : NULL);
861 /* no of elements given and we */
862 /* have generated for all of them */
865 // there has to be a better way
866 char *name=sym->opval.val->sym->name;
867 int lineno=sym->opval.val->sym->lineDef;
868 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
875 /* if we have not been given a size */
876 if (!DCL_ELEM (type))
878 DCL_ELEM (type) = size;
881 return decorateType (resolveSymbols (rast));
885 /*-----------------------------------------------------------------*/
886 /* createIvalCharPtr - generates initial values for char pointers */
887 /*-----------------------------------------------------------------*/
889 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
893 /* if this is a pointer & right is a literal array then */
894 /* just assignment will do */
895 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
896 SPEC_SCLS (iexpr->etype) == S_CODE)
897 && IS_ARRAY (iexpr->ftype)))
898 return newNode ('=', sym, iexpr);
900 /* left side is an array so we have to assign each */
902 if ((IS_LITERAL (iexpr->etype) ||
903 SPEC_SCLS (iexpr->etype) == S_CODE)
904 && IS_ARRAY (iexpr->ftype))
906 /* for each character generate an assignment */
907 /* to the array element */
908 char *s = SPEC_CVAL (iexpr->etype).v_char;
913 rast = newNode (NULLOP,
917 newAst_VALUE (valueFromLit ((float) i))),
918 newAst_VALUE (valueFromLit (*s))));
922 rast = newNode (NULLOP,
926 newAst_VALUE (valueFromLit ((float) i))),
927 newAst_VALUE (valueFromLit (*s))));
928 return decorateType (resolveSymbols (rast));
934 /*-----------------------------------------------------------------*/
935 /* createIvalPtr - generates initial value for pointers */
936 /*-----------------------------------------------------------------*/
938 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
944 if (ilist->type == INIT_DEEP)
945 ilist = ilist->init.deep;
947 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
949 /* if character pointer */
950 if (IS_CHAR (type->next))
951 if ((rast = createIvalCharPtr (sym, type, iexpr)))
954 return newNode ('=', sym, iexpr);
957 /*-----------------------------------------------------------------*/
958 /* createIval - generates code for initial value */
959 /*-----------------------------------------------------------------*/
961 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
968 /* if structure then */
969 if (IS_STRUCT (type))
970 rast = createIvalStruct (sym, type, ilist);
972 /* if this is a pointer */
974 rast = createIvalPtr (sym, type, ilist);
976 /* if this is an array */
978 rast = createIvalArray (sym, type, ilist);
980 /* if type is SPECIFIER */
982 rast = createIvalType (sym, type, ilist);
985 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
987 return decorateType (resolveSymbols (rast));
990 /*-----------------------------------------------------------------*/
991 /* initAggregates - initialises aggregate variables with initv */
992 /*-----------------------------------------------------------------*/
993 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
994 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
997 /*-----------------------------------------------------------------*/
998 /* gatherAutoInit - creates assignment expressions for initial */
1000 /*-----------------------------------------------------------------*/
1002 gatherAutoInit (symbol * autoChain)
1009 for (sym = autoChain; sym; sym = sym->next)
1012 /* resolve the symbols in the ival */
1014 resolveIvalSym (sym->ival);
1016 /* if this is a static variable & has an */
1017 /* initial value the code needs to be lifted */
1018 /* here to the main portion since they can be */
1019 /* initialised only once at the start */
1020 if (IS_STATIC (sym->etype) && sym->ival &&
1021 SPEC_SCLS (sym->etype) != S_CODE)
1025 /* insert the symbol into the symbol table */
1026 /* with level = 0 & name = rname */
1027 newSym = copySymbol (sym);
1028 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1030 /* now lift the code to main */
1031 if (IS_AGGREGATE (sym->type)) {
1032 work = initAggregates (sym, sym->ival, NULL);
1034 if (getNelements(sym->type, sym->ival)>1) {
1035 werror (W_EXCESS_INITIALIZERS, "scalar",
1036 sym->name, sym->lineDef);
1038 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1039 list2expr (sym->ival));
1042 setAstLineno (work, sym->lineDef);
1046 staticAutos = newNode (NULLOP, staticAutos, work);
1053 /* if there is an initial value */
1054 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1056 if (IS_AGGREGATE (sym->type)) {
1057 work = initAggregates (sym, sym->ival, NULL);
1059 if (getNelements(sym->type, sym->ival)>1) {
1060 werror (W_EXCESS_INITIALIZERS, "scalar",
1061 sym->name, sym->lineDef);
1063 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1064 list2expr (sym->ival));
1067 setAstLineno (work, sym->lineDef);
1070 init = newNode (NULLOP, init, work);
1079 /*-----------------------------------------------------------------*/
1080 /* stringToSymbol - creates a symbol from a literal string */
1081 /*-----------------------------------------------------------------*/
1083 stringToSymbol (value * val)
1085 char name[SDCC_NAME_MAX + 1];
1086 static int charLbl = 0;
1089 sprintf (name, "_str_%d", charLbl++);
1090 sym = newSymbol (name, 0); /* make it @ level 0 */
1091 strcpy (sym->rname, name);
1093 /* copy the type from the value passed */
1094 sym->type = copyLinkChain (val->type);
1095 sym->etype = getSpec (sym->type);
1096 /* change to storage class & output class */
1097 SPEC_SCLS (sym->etype) = S_CODE;
1098 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1099 SPEC_STAT (sym->etype) = 1;
1100 /* make the level & block = 0 */
1101 sym->block = sym->level = 0;
1103 /* create an ival */
1104 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1109 allocVariables (sym);
1112 return symbolVal (sym);
1116 /*-----------------------------------------------------------------*/
1117 /* processBlockVars - will go thru the ast looking for block if */
1118 /* a block is found then will allocate the syms */
1119 /* will also gather the auto inits present */
1120 /*-----------------------------------------------------------------*/
1122 processBlockVars (ast * tree, int *stack, int action)
1127 /* if this is a block */
1128 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1132 if (action == ALLOCATE)
1134 *stack += allocVariables (tree->values.sym);
1135 autoInit = gatherAutoInit (tree->values.sym);
1137 /* if there are auto inits then do them */
1139 tree->left = newNode (NULLOP, autoInit, tree->left);
1141 else /* action is deallocate */
1142 deallocLocal (tree->values.sym);
1145 processBlockVars (tree->left, stack, action);
1146 processBlockVars (tree->right, stack, action);
1150 /*-------------------------------------------------------------*/
1151 /* constExprTree - returns TRUE if this tree is a constant */
1153 /*-------------------------------------------------------------*/
1154 bool constExprTree (ast *cexpr) {
1160 cexpr = decorateType (resolveSymbols (cexpr));
1162 switch (cexpr->type)
1165 if (IS_AST_LIT_VALUE(cexpr)) {
1166 // this is a literal
1169 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1170 // a function's address will never change
1173 if (IS_AST_SYM_VALUE(cexpr) &&
1174 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1175 // a symbol in code space will never change
1176 // This is only for the 'char *s="hallo"' case and will have to leave
1181 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1182 "unexpected link in expression tree\n");
1185 if (cexpr->opval.op==ARRAYINIT) {
1186 // this is a list of literals
1189 if (cexpr->opval.op=='=') {
1190 return constExprTree(cexpr->right);
1192 if (cexpr->opval.op==CAST) {
1193 // jwk: cast ignored, maybe we should throw a warning here
1194 return constExprTree(cexpr->right);
1196 if (cexpr->opval.op=='&') {
1199 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1202 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1209 /*-----------------------------------------------------------------*/
1210 /* constExprValue - returns the value of a constant expression */
1211 /* or NULL if it is not a constant expression */
1212 /*-----------------------------------------------------------------*/
1214 constExprValue (ast * cexpr, int check)
1216 cexpr = decorateType (resolveSymbols (cexpr));
1218 /* if this is not a constant then */
1219 if (!IS_LITERAL (cexpr->ftype))
1221 /* then check if this is a literal array
1223 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1224 SPEC_CVAL (cexpr->etype).v_char &&
1225 IS_ARRAY (cexpr->ftype))
1227 value *val = valFromType (cexpr->ftype);
1228 SPEC_SCLS (val->etype) = S_LITERAL;
1229 val->sym = cexpr->opval.val->sym;
1230 val->sym->type = copyLinkChain (cexpr->ftype);
1231 val->sym->etype = getSpec (val->sym->type);
1232 strcpy (val->name, cexpr->opval.val->sym->rname);
1236 /* if we are casting a literal value then */
1237 if (IS_AST_OP (cexpr) &&
1238 cexpr->opval.op == CAST &&
1239 IS_LITERAL (cexpr->left->ftype))
1240 return valCastLiteral (cexpr->ftype,
1241 floatFromVal (cexpr->left->opval.val));
1243 if (IS_AST_VALUE (cexpr))
1244 return cexpr->opval.val;
1247 werror (E_CONST_EXPECTED, "found expression");
1252 /* return the value */
1253 return cexpr->opval.val;
1257 /*-----------------------------------------------------------------*/
1258 /* isLabelInAst - will return true if a given label is found */
1259 /*-----------------------------------------------------------------*/
1261 isLabelInAst (symbol * label, ast * tree)
1263 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1266 if (IS_AST_OP (tree) &&
1267 tree->opval.op == LABEL &&
1268 isSymbolEqual (AST_SYMBOL (tree->left), label))
1271 return isLabelInAst (label, tree->right) &&
1272 isLabelInAst (label, tree->left);
1276 /*-----------------------------------------------------------------*/
1277 /* isLoopCountable - return true if the loop count can be determi- */
1278 /* -ned at compile time . */
1279 /*-----------------------------------------------------------------*/
1281 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1282 symbol ** sym, ast ** init, ast ** end)
1285 /* the loop is considered countable if the following
1286 conditions are true :-
1288 a) initExpr :- <sym> = <const>
1289 b) condExpr :- <sym> < <const1>
1290 c) loopExpr :- <sym> ++
1293 /* first check the initExpr */
1294 if (IS_AST_OP (initExpr) &&
1295 initExpr->opval.op == '=' && /* is assignment */
1296 IS_AST_SYM_VALUE (initExpr->left))
1297 { /* left is a symbol */
1299 *sym = AST_SYMBOL (initExpr->left);
1300 *init = initExpr->right;
1305 /* for now the symbol has to be of
1307 if (!IS_INTEGRAL ((*sym)->type))
1310 /* now check condExpr */
1311 if (IS_AST_OP (condExpr))
1314 switch (condExpr->opval.op)
1317 if (IS_AST_SYM_VALUE (condExpr->left) &&
1318 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1319 IS_AST_LIT_VALUE (condExpr->right))
1321 *end = condExpr->right;
1327 if (IS_AST_OP (condExpr->left) &&
1328 condExpr->left->opval.op == '>' &&
1329 IS_AST_LIT_VALUE (condExpr->left->right) &&
1330 IS_AST_SYM_VALUE (condExpr->left->left) &&
1331 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1334 *end = newNode ('+', condExpr->left->right,
1335 newAst_VALUE (constVal ("1")));
1346 /* check loop expression is of the form <sym>++ */
1347 if (!IS_AST_OP (loopExpr))
1350 /* check if <sym> ++ */
1351 if (loopExpr->opval.op == INC_OP)
1357 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1358 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1365 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1366 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1374 if (loopExpr->opval.op == ADD_ASSIGN)
1377 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1378 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1379 IS_AST_LIT_VALUE (loopExpr->right) &&
1380 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1388 /*-----------------------------------------------------------------*/
1389 /* astHasVolatile - returns true if ast contains any volatile */
1390 /*-----------------------------------------------------------------*/
1392 astHasVolatile (ast * tree)
1397 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1400 if (IS_AST_OP (tree))
1401 return astHasVolatile (tree->left) ||
1402 astHasVolatile (tree->right);
1407 /*-----------------------------------------------------------------*/
1408 /* astHasPointer - return true if the ast contains any ptr variable */
1409 /*-----------------------------------------------------------------*/
1411 astHasPointer (ast * tree)
1416 if (IS_AST_LINK (tree))
1419 /* if we hit an array expression then check
1420 only the left side */
1421 if (IS_AST_OP (tree) && tree->opval.op == '[')
1422 return astHasPointer (tree->left);
1424 if (IS_AST_VALUE (tree))
1425 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1427 return astHasPointer (tree->left) ||
1428 astHasPointer (tree->right);
1432 /*-----------------------------------------------------------------*/
1433 /* astHasSymbol - return true if the ast has the given symbol */
1434 /*-----------------------------------------------------------------*/
1436 astHasSymbol (ast * tree, symbol * sym)
1438 if (!tree || IS_AST_LINK (tree))
1441 if (IS_AST_VALUE (tree))
1443 if (IS_AST_SYM_VALUE (tree))
1444 return isSymbolEqual (AST_SYMBOL (tree), sym);
1449 return astHasSymbol (tree->left, sym) ||
1450 astHasSymbol (tree->right, sym);
1453 /*-----------------------------------------------------------------*/
1454 /* astHasDeref - return true if the ast has an indirect access */
1455 /*-----------------------------------------------------------------*/
1457 astHasDeref (ast * tree)
1459 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1462 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1464 return astHasDeref (tree->left) || astHasDeref (tree->right);
1467 /*-----------------------------------------------------------------*/
1468 /* isConformingBody - the loop body has to conform to a set of rules */
1469 /* for the loop to be considered reversible read on for rules */
1470 /*-----------------------------------------------------------------*/
1472 isConformingBody (ast * pbody, symbol * sym, ast * body)
1475 /* we are going to do a pre-order traversal of the
1476 tree && check for the following conditions. (essentially
1477 a set of very shallow tests )
1478 a) the sym passed does not participate in
1479 any arithmetic operation
1480 b) There are no function calls
1481 c) all jumps are within the body
1482 d) address of loop control variable not taken
1483 e) if an assignment has a pointer on the
1484 left hand side make sure right does not have
1485 loop control variable */
1487 /* if we reach the end or a leaf then true */
1488 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1492 /* if anything else is "volatile" */
1493 if (IS_VOLATILE (TETYPE (pbody)))
1496 /* we will walk the body in a pre-order traversal for
1498 switch (pbody->opval.op)
1500 /*------------------------------------------------------------------*/
1502 return isConformingBody (pbody->right, sym, body);
1504 /*------------------------------------------------------------------*/
1509 /*------------------------------------------------------------------*/
1510 case INC_OP: /* incerement operator unary so left only */
1513 /* sure we are not sym is not modified */
1515 IS_AST_SYM_VALUE (pbody->left) &&
1516 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1520 IS_AST_SYM_VALUE (pbody->right) &&
1521 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1526 /*------------------------------------------------------------------*/
1528 case '*': /* can be unary : if right is null then unary operation */
1533 /* if right is NULL then unary operation */
1534 /*------------------------------------------------------------------*/
1535 /*----------------------------*/
1537 /*----------------------------*/
1540 if (IS_AST_SYM_VALUE (pbody->left) &&
1541 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1544 return isConformingBody (pbody->left, sym, body);
1548 if (astHasSymbol (pbody->left, sym) ||
1549 astHasSymbol (pbody->right, sym))
1554 /*------------------------------------------------------------------*/
1562 if (IS_AST_SYM_VALUE (pbody->left) &&
1563 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1566 if (IS_AST_SYM_VALUE (pbody->right) &&
1567 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1570 return isConformingBody (pbody->left, sym, body) &&
1571 isConformingBody (pbody->right, sym, body);
1578 if (IS_AST_SYM_VALUE (pbody->left) &&
1579 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1581 return isConformingBody (pbody->left, sym, body);
1583 /*------------------------------------------------------------------*/
1595 case SIZEOF: /* evaluate wihout code generation */
1597 return isConformingBody (pbody->left, sym, body) &&
1598 isConformingBody (pbody->right, sym, body);
1600 /*------------------------------------------------------------------*/
1603 /* if left has a pointer & right has loop
1604 control variable then we cannot */
1605 if (astHasPointer (pbody->left) &&
1606 astHasSymbol (pbody->right, sym))
1608 if (astHasVolatile (pbody->left))
1611 if (IS_AST_SYM_VALUE (pbody->left) &&
1612 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1615 if (astHasVolatile (pbody->left))
1618 if (astHasDeref(pbody->right)) return FALSE;
1620 return isConformingBody (pbody->left, sym, body) &&
1621 isConformingBody (pbody->right, sym, body);
1632 assert ("Parser should not have generated this\n");
1634 /*------------------------------------------------------------------*/
1635 /*----------------------------*/
1636 /* comma operator */
1637 /*----------------------------*/
1639 return isConformingBody (pbody->left, sym, body) &&
1640 isConformingBody (pbody->right, sym, body);
1642 /*------------------------------------------------------------------*/
1643 /*----------------------------*/
1645 /*----------------------------*/
1649 /*------------------------------------------------------------------*/
1650 /*----------------------------*/
1651 /* return statement */
1652 /*----------------------------*/
1657 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1662 if (astHasSymbol (pbody->left, sym))
1669 return isConformingBody (pbody->left, sym, body) &&
1670 isConformingBody (pbody->right, sym, body);
1676 /*-----------------------------------------------------------------*/
1677 /* isLoopReversible - takes a for loop as input && returns true */
1678 /* if the for loop is reversible. If yes will set the value of */
1679 /* the loop control var & init value & termination value */
1680 /*-----------------------------------------------------------------*/
1682 isLoopReversible (ast * loop, symbol ** loopCntrl,
1683 ast ** init, ast ** end)
1685 /* if option says don't do it then don't */
1686 if (optimize.noLoopReverse)
1688 /* there are several tests to determine this */
1690 /* for loop has to be of the form
1691 for ( <sym> = <const1> ;
1692 [<sym> < <const2>] ;
1693 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1695 if (!isLoopCountable (AST_FOR (loop, initExpr),
1696 AST_FOR (loop, condExpr),
1697 AST_FOR (loop, loopExpr),
1698 loopCntrl, init, end))
1701 /* now do some serious checking on the body of the loop
1704 return isConformingBody (loop->left, *loopCntrl, loop->left);
1708 /*-----------------------------------------------------------------*/
1709 /* replLoopSym - replace the loop sym by loop sym -1 */
1710 /*-----------------------------------------------------------------*/
1712 replLoopSym (ast * body, symbol * sym)
1715 if (!body || IS_AST_LINK (body))
1718 if (IS_AST_SYM_VALUE (body))
1721 if (isSymbolEqual (AST_SYMBOL (body), sym))
1725 body->opval.op = '-';
1726 body->left = newAst_VALUE (symbolVal (sym));
1727 body->right = newAst_VALUE (constVal ("1"));
1735 replLoopSym (body->left, sym);
1736 replLoopSym (body->right, sym);
1740 /*-----------------------------------------------------------------*/
1741 /* reverseLoop - do the actual loop reversal */
1742 /*-----------------------------------------------------------------*/
1744 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1748 /* create the following tree
1753 if (sym) goto for_continue ;
1756 /* put it together piece by piece */
1757 rloop = newNode (NULLOP,
1758 createIf (newAst_VALUE (symbolVal (sym)),
1760 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1763 newAst_VALUE (symbolVal (sym)),
1766 replLoopSym (loop->left, sym);
1768 rloop = newNode (NULLOP,
1770 newAst_VALUE (symbolVal (sym)),
1771 newNode ('-', end, init)),
1772 createLabel (AST_FOR (loop, continueLabel),
1776 newNode (SUB_ASSIGN,
1777 newAst_VALUE (symbolVal (sym)),
1778 newAst_VALUE (constVal ("1"))),
1781 return decorateType (rloop);
1785 /*-----------------------------------------------------------------*/
1786 /* decorateType - compute type for this tree also does type cheking */
1787 /* this is done bottom up, since type have to flow upwards */
1788 /* it also does constant folding, and paramater checking */
1789 /*-----------------------------------------------------------------*/
1791 decorateType (ast * tree)
1799 /* if already has type then do nothing */
1800 if (tree->decorated)
1803 tree->decorated = 1;
1805 /* print the line */
1806 /* if not block & function */
1807 if (tree->type == EX_OP &&
1808 (tree->opval.op != FUNCTION &&
1809 tree->opval.op != BLOCK &&
1810 tree->opval.op != NULLOP))
1812 filename = tree->filename;
1813 lineno = tree->lineno;
1816 /* if any child is an error | this one is an error do nothing */
1817 if (tree->isError ||
1818 (tree->left && tree->left->isError) ||
1819 (tree->right && tree->right->isError))
1822 /*------------------------------------------------------------------*/
1823 /*----------------------------*/
1824 /* leaf has been reached */
1825 /*----------------------------*/
1826 /* if this is of type value */
1827 /* just get the type */
1828 if (tree->type == EX_VALUE)
1831 if (IS_LITERAL (tree->opval.val->etype))
1834 /* if this is a character array then declare it */
1835 if (IS_ARRAY (tree->opval.val->type))
1836 tree->opval.val = stringToSymbol (tree->opval.val);
1838 /* otherwise just copy the type information */
1839 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1843 if (tree->opval.val->sym)
1845 /* if the undefined flag is set then give error message */
1846 if (tree->opval.val->sym->undefined)
1848 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1850 TTYPE (tree) = TETYPE (tree) =
1851 tree->opval.val->type = tree->opval.val->sym->type =
1852 tree->opval.val->etype = tree->opval.val->sym->etype =
1853 copyLinkChain (INTTYPE);
1858 /* if impilicit i.e. struct/union member then no type */
1859 if (tree->opval.val->sym->implicit)
1860 TTYPE (tree) = TETYPE (tree) = NULL;
1865 /* else copy the type */
1866 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1868 /* and mark it as referenced */
1869 tree->opval.val->sym->isref = 1;
1877 /* if type link for the case of cast */
1878 if (tree->type == EX_LINK)
1880 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1887 dtl = decorateType (tree->left);
1888 /* delay right side for '?' operator since conditional macro expansions might
1890 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1892 /* this is to take care of situations
1893 when the tree gets rewritten */
1894 if (dtl != tree->left)
1896 if (dtr != tree->right)
1900 /* depending on type of operator do */
1902 switch (tree->opval.op)
1904 /*------------------------------------------------------------------*/
1905 /*----------------------------*/
1907 /*----------------------------*/
1910 /* determine which is the array & which the index */
1911 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1914 ast *tempTree = tree->left;
1915 tree->left = tree->right;
1916 tree->right = tempTree;
1919 /* first check if this is a array or a pointer */
1920 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1922 werror (E_NEED_ARRAY_PTR, "[]");
1923 goto errorTreeReturn;
1926 /* check if the type of the idx */
1927 if (!IS_INTEGRAL (RTYPE (tree)))
1929 werror (E_IDX_NOT_INT);
1930 goto errorTreeReturn;
1933 /* if the left is an rvalue then error */
1936 werror (E_LVALUE_REQUIRED, "array access");
1937 goto errorTreeReturn;
1940 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1941 if (IS_PTR(LTYPE(tree))) {
1942 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1946 /*------------------------------------------------------------------*/
1947 /*----------------------------*/
1949 /*----------------------------*/
1951 /* if this is not a structure */
1952 if (!IS_STRUCT (LTYPE (tree)))
1954 werror (E_STRUCT_UNION, ".");
1955 goto errorTreeReturn;
1957 TTYPE (tree) = structElemType (LTYPE (tree),
1958 (tree->right->type == EX_VALUE ?
1959 tree->right->opval.val : NULL));
1960 TETYPE (tree) = getSpec (TTYPE (tree));
1963 /*------------------------------------------------------------------*/
1964 /*----------------------------*/
1965 /* struct/union pointer */
1966 /*----------------------------*/
1968 /* if not pointer to a structure */
1969 if (!IS_PTR (LTYPE (tree)))
1971 werror (E_PTR_REQD);
1972 goto errorTreeReturn;
1975 if (!IS_STRUCT (LTYPE (tree)->next))
1977 werror (E_STRUCT_UNION, "->");
1978 goto errorTreeReturn;
1981 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1982 (tree->right->type == EX_VALUE ?
1983 tree->right->opval.val : NULL));
1984 TETYPE (tree) = getSpec (TTYPE (tree));
1986 /* adjust the storage class */
1987 switch (DCL_TYPE(tree->left->ftype)) {
1991 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
1994 SPEC_SCLS(TETYPE(tree)) = S_CODE;
1999 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2002 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2005 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2014 /*------------------------------------------------------------------*/
2015 /*----------------------------*/
2016 /* ++/-- operation */
2017 /*----------------------------*/
2018 case INC_OP: /* incerement operator unary so left only */
2021 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2022 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2023 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2024 werror (E_CODE_WRITE, "++/--");
2033 /*------------------------------------------------------------------*/
2034 /*----------------------------*/
2036 /*----------------------------*/
2037 case '&': /* can be unary */
2038 /* if right is NULL then unary operation */
2039 if (tree->right) /* not an unary operation */
2042 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2044 werror (E_BITWISE_OP);
2045 werror (W_CONTINUE, "left & right types are ");
2046 printTypeChain (LTYPE (tree), stderr);
2047 fprintf (stderr, ",");
2048 printTypeChain (RTYPE (tree), stderr);
2049 fprintf (stderr, "\n");
2050 goto errorTreeReturn;
2053 /* if they are both literal */
2054 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2056 tree->type = EX_VALUE;
2057 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2058 valFromType (RETYPE (tree)), '&');
2060 tree->right = tree->left = NULL;
2061 TETYPE (tree) = tree->opval.val->etype;
2062 TTYPE (tree) = tree->opval.val->type;
2066 /* see if this is a GETHBIT operation if yes
2069 ast *otree = optimizeGetHbit (tree);
2072 return decorateType (otree);
2076 computeType (LTYPE (tree), RTYPE (tree));
2077 TETYPE (tree) = getSpec (TTYPE (tree));
2079 LRVAL (tree) = RRVAL (tree) = 1;
2083 /*------------------------------------------------------------------*/
2084 /*----------------------------*/
2086 /*----------------------------*/
2088 p->class = DECLARATOR;
2089 /* if bit field then error */
2090 if (IS_BITVAR (tree->left->etype))
2092 werror (E_ILLEGAL_ADDR, "address of bit variable");
2093 goto errorTreeReturn;
2096 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2098 werror (E_ILLEGAL_ADDR, "address of register variable");
2099 goto errorTreeReturn;
2102 if (IS_FUNC (LTYPE (tree)))
2104 werror (E_ILLEGAL_ADDR, "address of function");
2105 goto errorTreeReturn;
2108 if (IS_LITERAL(LTYPE(tree)))
2110 werror (E_ILLEGAL_ADDR, "address of literal");
2111 goto errorTreeReturn;
2116 werror (E_LVALUE_REQUIRED, "address of");
2117 goto errorTreeReturn;
2119 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2121 DCL_TYPE (p) = CPOINTER;
2122 DCL_PTR_CONST (p) = port->mem.code_ro;
2124 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2125 DCL_TYPE (p) = FPOINTER;
2126 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2127 DCL_TYPE (p) = PPOINTER;
2128 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2129 DCL_TYPE (p) = IPOINTER;
2130 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2131 DCL_TYPE (p) = EEPPOINTER;
2132 else if (SPEC_OCLS(tree->left->etype))
2133 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2135 DCL_TYPE (p) = POINTER;
2137 if (IS_AST_SYM_VALUE (tree->left))
2139 AST_SYMBOL (tree->left)->addrtaken = 1;
2140 AST_SYMBOL (tree->left)->allocreq = 1;
2143 p->next = LTYPE (tree);
2145 TETYPE (tree) = getSpec (TTYPE (tree));
2146 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2147 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2152 /*------------------------------------------------------------------*/
2153 /*----------------------------*/
2155 /*----------------------------*/
2157 /* if the rewrite succeeds then don't go any furthur */
2159 ast *wtree = optimizeRRCRLC (tree);
2161 return decorateType (wtree);
2163 /*------------------------------------------------------------------*/
2164 /*----------------------------*/
2166 /*----------------------------*/
2168 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2170 werror (E_BITWISE_OP);
2171 werror (W_CONTINUE, "left & right types are ");
2172 printTypeChain (LTYPE (tree), stderr);
2173 fprintf (stderr, ",");
2174 printTypeChain (RTYPE (tree), stderr);
2175 fprintf (stderr, "\n");
2176 goto errorTreeReturn;
2179 /* if they are both literal then */
2180 /* rewrite the tree */
2181 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2183 tree->type = EX_VALUE;
2184 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2185 valFromType (RETYPE (tree)),
2187 tree->right = tree->left = NULL;
2188 TETYPE (tree) = tree->opval.val->etype;
2189 TTYPE (tree) = tree->opval.val->type;
2192 LRVAL (tree) = RRVAL (tree) = 1;
2193 TETYPE (tree) = getSpec (TTYPE (tree) =
2194 computeType (LTYPE (tree),
2197 /*------------------------------------------------------------------*/
2198 /*----------------------------*/
2200 /*----------------------------*/
2202 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2204 werror (E_INVALID_OP, "divide");
2205 goto errorTreeReturn;
2207 /* if they are both literal then */
2208 /* rewrite the tree */
2209 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2211 tree->type = EX_VALUE;
2212 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2213 valFromType (RETYPE (tree)));
2214 tree->right = tree->left = NULL;
2215 TETYPE (tree) = getSpec (TTYPE (tree) =
2216 tree->opval.val->type);
2219 LRVAL (tree) = RRVAL (tree) = 1;
2220 TETYPE (tree) = getSpec (TTYPE (tree) =
2221 computeType (LTYPE (tree),
2225 /*------------------------------------------------------------------*/
2226 /*----------------------------*/
2228 /*----------------------------*/
2230 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2232 werror (E_BITWISE_OP);
2233 werror (W_CONTINUE, "left & right types are ");
2234 printTypeChain (LTYPE (tree), stderr);
2235 fprintf (stderr, ",");
2236 printTypeChain (RTYPE (tree), stderr);
2237 fprintf (stderr, "\n");
2238 goto errorTreeReturn;
2240 /* if they are both literal then */
2241 /* rewrite the tree */
2242 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2244 tree->type = EX_VALUE;
2245 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2246 valFromType (RETYPE (tree)));
2247 tree->right = tree->left = NULL;
2248 TETYPE (tree) = getSpec (TTYPE (tree) =
2249 tree->opval.val->type);
2252 LRVAL (tree) = RRVAL (tree) = 1;
2253 TETYPE (tree) = getSpec (TTYPE (tree) =
2254 computeType (LTYPE (tree),
2258 /*------------------------------------------------------------------*/
2259 /*----------------------------*/
2260 /* address dereference */
2261 /*----------------------------*/
2262 case '*': /* can be unary : if right is null then unary operation */
2265 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2267 werror (E_PTR_REQD);
2268 goto errorTreeReturn;
2273 werror (E_LVALUE_REQUIRED, "pointer deref");
2274 goto errorTreeReturn;
2276 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2277 LTYPE (tree)->next : NULL);
2278 TETYPE (tree) = getSpec (TTYPE (tree));
2279 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2283 /*------------------------------------------------------------------*/
2284 /*----------------------------*/
2285 /* multiplication */
2286 /*----------------------------*/
2287 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2289 werror (E_INVALID_OP, "multiplication");
2290 goto errorTreeReturn;
2293 /* if they are both literal then */
2294 /* rewrite the tree */
2295 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2297 tree->type = EX_VALUE;
2298 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2299 valFromType (RETYPE (tree)));
2300 tree->right = tree->left = NULL;
2301 TETYPE (tree) = getSpec (TTYPE (tree) =
2302 tree->opval.val->type);
2306 /* if left is a literal exchange left & right */
2307 if (IS_LITERAL (LTYPE (tree)))
2309 ast *tTree = tree->left;
2310 tree->left = tree->right;
2311 tree->right = tTree;
2314 LRVAL (tree) = RRVAL (tree) = 1;
2315 /* promote result to int if left & right are char
2316 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2317 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2318 TETYPE (tree) = getSpec (TTYPE (tree) =
2319 computeType (LTYPE (tree),
2321 SPEC_NOUN(TETYPE(tree)) = V_INT;
2323 TETYPE (tree) = getSpec (TTYPE (tree) =
2324 computeType (LTYPE (tree),
2329 /*------------------------------------------------------------------*/
2330 /*----------------------------*/
2331 /* unary '+' operator */
2332 /*----------------------------*/
2337 if (!IS_INTEGRAL (LTYPE (tree)))
2339 werror (E_UNARY_OP, '+');
2340 goto errorTreeReturn;
2343 /* if left is a literal then do it */
2344 if (IS_LITERAL (LTYPE (tree)))
2346 tree->type = EX_VALUE;
2347 tree->opval.val = valFromType (LETYPE (tree));
2349 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2353 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2357 /*------------------------------------------------------------------*/
2358 /*----------------------------*/
2360 /*----------------------------*/
2362 /* this is not a unary operation */
2363 /* if both pointers then problem */
2364 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2365 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2367 werror (E_PTR_PLUS_PTR);
2368 goto errorTreeReturn;
2371 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2372 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2374 werror (E_PLUS_INVALID, "+");
2375 goto errorTreeReturn;
2378 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2379 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2381 werror (E_PLUS_INVALID, "+");
2382 goto errorTreeReturn;
2384 /* if they are both literal then */
2385 /* rewrite the tree */
2386 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2388 tree->type = EX_VALUE;
2389 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2390 valFromType (RETYPE (tree)));
2391 tree->right = tree->left = NULL;
2392 TETYPE (tree) = getSpec (TTYPE (tree) =
2393 tree->opval.val->type);
2397 /* if the right is a pointer or left is a literal
2398 xchange left & right */
2399 if (IS_ARRAY (RTYPE (tree)) ||
2400 IS_PTR (RTYPE (tree)) ||
2401 IS_LITERAL (LTYPE (tree)))
2403 ast *tTree = tree->left;
2404 tree->left = tree->right;
2405 tree->right = tTree;
2408 LRVAL (tree) = RRVAL (tree) = 1;
2409 /* if the left is a pointer */
2410 if (IS_PTR (LTYPE (tree)))
2411 TETYPE (tree) = getSpec (TTYPE (tree) =
2414 TETYPE (tree) = getSpec (TTYPE (tree) =
2415 computeType (LTYPE (tree),
2419 /*------------------------------------------------------------------*/
2420 /*----------------------------*/
2422 /*----------------------------*/
2423 case '-': /* can be unary */
2424 /* if right is null then unary */
2428 if (!IS_ARITHMETIC (LTYPE (tree)))
2430 werror (E_UNARY_OP, tree->opval.op);
2431 goto errorTreeReturn;
2434 /* if left is a literal then do it */
2435 if (IS_LITERAL (LTYPE (tree)))
2437 tree->type = EX_VALUE;
2438 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2440 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2441 SPEC_USIGN(TETYPE(tree)) = 0;
2445 TTYPE (tree) = LTYPE (tree);
2449 /*------------------------------------------------------------------*/
2450 /*----------------------------*/
2452 /*----------------------------*/
2454 if (!(IS_PTR (LTYPE (tree)) ||
2455 IS_ARRAY (LTYPE (tree)) ||
2456 IS_ARITHMETIC (LTYPE (tree))))
2458 werror (E_PLUS_INVALID, "-");
2459 goto errorTreeReturn;
2462 if (!(IS_PTR (RTYPE (tree)) ||
2463 IS_ARRAY (RTYPE (tree)) ||
2464 IS_ARITHMETIC (RTYPE (tree))))
2466 werror (E_PLUS_INVALID, "-");
2467 goto errorTreeReturn;
2470 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2471 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2472 IS_INTEGRAL (RTYPE (tree))))
2474 werror (E_PLUS_INVALID, "-");
2475 goto errorTreeReturn;
2478 /* if they are both literal then */
2479 /* rewrite the tree */
2480 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2482 tree->type = EX_VALUE;
2483 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2484 valFromType (RETYPE (tree)));
2485 tree->right = tree->left = NULL;
2486 TETYPE (tree) = getSpec (TTYPE (tree) =
2487 tree->opval.val->type);
2491 /* if the left & right are equal then zero */
2492 if (isAstEqual (tree->left, tree->right))
2494 tree->type = EX_VALUE;
2495 tree->left = tree->right = NULL;
2496 tree->opval.val = constVal ("0");
2497 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2501 /* if both of them are pointers or arrays then */
2502 /* the result is going to be an integer */
2503 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2504 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2505 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2507 /* if only the left is a pointer */
2508 /* then result is a pointer */
2509 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2510 TETYPE (tree) = getSpec (TTYPE (tree) =
2513 TETYPE (tree) = getSpec (TTYPE (tree) =
2514 computeType (LTYPE (tree),
2516 LRVAL (tree) = RRVAL (tree) = 1;
2519 /*------------------------------------------------------------------*/
2520 /*----------------------------*/
2522 /*----------------------------*/
2524 /* can be only integral type */
2525 if (!IS_INTEGRAL (LTYPE (tree)))
2527 werror (E_UNARY_OP, tree->opval.op);
2528 goto errorTreeReturn;
2531 /* if left is a literal then do it */
2532 if (IS_LITERAL (LTYPE (tree)))
2534 tree->type = EX_VALUE;
2535 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2537 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2541 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2544 /*------------------------------------------------------------------*/
2545 /*----------------------------*/
2547 /*----------------------------*/
2549 /* can be pointer */
2550 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2551 !IS_PTR (LTYPE (tree)) &&
2552 !IS_ARRAY (LTYPE (tree)))
2554 werror (E_UNARY_OP, tree->opval.op);
2555 goto errorTreeReturn;
2558 /* if left is a literal then do it */
2559 if (IS_LITERAL (LTYPE (tree)))
2561 tree->type = EX_VALUE;
2562 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2564 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2568 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2571 /*------------------------------------------------------------------*/
2572 /*----------------------------*/
2574 /*----------------------------*/
2577 TTYPE (tree) = LTYPE (tree);
2578 TETYPE (tree) = LETYPE (tree);
2582 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2587 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2589 werror (E_SHIFT_OP_INVALID);
2590 werror (W_CONTINUE, "left & right types are ");
2591 printTypeChain (LTYPE (tree), stderr);
2592 fprintf (stderr, ",");
2593 printTypeChain (RTYPE (tree), stderr);
2594 fprintf (stderr, "\n");
2595 goto errorTreeReturn;
2598 /* if they are both literal then */
2599 /* rewrite the tree */
2600 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2602 tree->type = EX_VALUE;
2603 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2604 valFromType (RETYPE (tree)),
2605 (tree->opval.op == LEFT_OP ? 1 : 0));
2606 tree->right = tree->left = NULL;
2607 TETYPE (tree) = getSpec (TTYPE (tree) =
2608 tree->opval.val->type);
2611 /* if only the right side is a literal & we are
2612 shifting more than size of the left operand then zero */
2613 if (IS_LITERAL (RTYPE (tree)) &&
2614 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2615 (getSize (LTYPE (tree)) * 8))
2617 werror (W_SHIFT_CHANGED,
2618 (tree->opval.op == LEFT_OP ? "left" : "right"));
2619 tree->type = EX_VALUE;
2620 tree->left = tree->right = NULL;
2621 tree->opval.val = constVal ("0");
2622 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2625 LRVAL (tree) = RRVAL (tree) = 1;
2626 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2628 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2632 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2636 /*------------------------------------------------------------------*/
2637 /*----------------------------*/
2639 /*----------------------------*/
2640 case CAST: /* change the type */
2641 /* cannot cast to an aggregate type */
2642 if (IS_AGGREGATE (LTYPE (tree)))
2644 werror (E_CAST_ILLEGAL);
2645 goto errorTreeReturn;
2648 /* make sure the type is complete and sane */
2649 checkTypeSanity(LETYPE(tree), "(cast)");
2652 /* if the right is a literal replace the tree */
2653 if (IS_LITERAL (RETYPE (tree))) {
2654 if (!IS_PTR (LTYPE (tree))) {
2655 tree->type = EX_VALUE;
2657 valCastLiteral (LTYPE (tree),
2658 floatFromVal (valFromType (RETYPE (tree))));
2661 TTYPE (tree) = tree->opval.val->type;
2662 tree->values.literalFromCast = 1;
2663 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2664 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2665 sym_link *rest = LTYPE(tree)->next;
2666 werror(W_LITERAL_GENERIC);
2667 TTYPE(tree) = newLink();
2668 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2669 TTYPE(tree)->next = rest;
2670 tree->left->opval.lnk = TTYPE(tree);
2673 TTYPE (tree) = LTYPE (tree);
2677 TTYPE (tree) = LTYPE (tree);
2681 /* if pointer to struct then check names */
2682 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2683 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2684 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2685 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2687 /* if the right is a literal replace the tree */
2688 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2689 tree->type = EX_VALUE;
2691 valCastLiteral (LTYPE (tree),
2692 floatFromVal (valFromType (RETYPE (tree))));
2695 TTYPE (tree) = tree->opval.val->type;
2696 tree->values.literalFromCast = 1;
2698 TTYPE (tree) = LTYPE (tree);
2702 TETYPE (tree) = getSpec (TTYPE (tree));
2706 /*------------------------------------------------------------------*/
2707 /*----------------------------*/
2708 /* logical &&, || */
2709 /*----------------------------*/
2712 /* each must me arithmetic type or be a pointer */
2713 if (!IS_PTR (LTYPE (tree)) &&
2714 !IS_ARRAY (LTYPE (tree)) &&
2715 !IS_INTEGRAL (LTYPE (tree)))
2717 werror (E_COMPARE_OP);
2718 goto errorTreeReturn;
2721 if (!IS_PTR (RTYPE (tree)) &&
2722 !IS_ARRAY (RTYPE (tree)) &&
2723 !IS_INTEGRAL (RTYPE (tree)))
2725 werror (E_COMPARE_OP);
2726 goto errorTreeReturn;
2728 /* if they are both literal then */
2729 /* rewrite the tree */
2730 if (IS_LITERAL (RTYPE (tree)) &&
2731 IS_LITERAL (LTYPE (tree)))
2733 tree->type = EX_VALUE;
2734 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2735 valFromType (RETYPE (tree)),
2737 tree->right = tree->left = NULL;
2738 TETYPE (tree) = getSpec (TTYPE (tree) =
2739 tree->opval.val->type);
2742 LRVAL (tree) = RRVAL (tree) = 1;
2743 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2746 /*------------------------------------------------------------------*/
2747 /*----------------------------*/
2748 /* comparison operators */
2749 /*----------------------------*/
2757 ast *lt = optimizeCompare (tree);
2763 /* if they are pointers they must be castable */
2764 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2766 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2768 werror (E_COMPARE_OP);
2769 fprintf (stderr, "comparing type ");
2770 printTypeChain (LTYPE (tree), stderr);
2771 fprintf (stderr, "to type ");
2772 printTypeChain (RTYPE (tree), stderr);
2773 fprintf (stderr, "\n");
2774 goto errorTreeReturn;
2777 /* else they should be promotable to one another */
2780 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2781 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2783 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2785 werror (E_COMPARE_OP);
2786 fprintf (stderr, "comparing type ");
2787 printTypeChain (LTYPE (tree), stderr);
2788 fprintf (stderr, "to type ");
2789 printTypeChain (RTYPE (tree), stderr);
2790 fprintf (stderr, "\n");
2791 goto errorTreeReturn;
2794 /* if unsigned value < 0 then always false */
2795 /* if (unsigned value) > 0 then (unsigned value) */
2796 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2797 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2799 if (tree->opval.op == '<') {
2802 if (tree->opval.op == '>') {
2806 /* if they are both literal then */
2807 /* rewrite the tree */
2808 if (IS_LITERAL (RTYPE (tree)) &&
2809 IS_LITERAL (LTYPE (tree)))
2811 tree->type = EX_VALUE;
2812 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2813 valFromType (RETYPE (tree)),
2815 tree->right = tree->left = NULL;
2816 TETYPE (tree) = getSpec (TTYPE (tree) =
2817 tree->opval.val->type);
2820 LRVAL (tree) = RRVAL (tree) = 1;
2821 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2824 /*------------------------------------------------------------------*/
2825 /*----------------------------*/
2827 /*----------------------------*/
2828 case SIZEOF: /* evaluate wihout code generation */
2829 /* change the type to a integer */
2830 tree->type = EX_VALUE;
2831 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2832 tree->opval.val = constVal (buffer);
2833 tree->right = tree->left = NULL;
2834 TETYPE (tree) = getSpec (TTYPE (tree) =
2835 tree->opval.val->type);
2838 /*------------------------------------------------------------------*/
2839 /*----------------------------*/
2841 /*----------------------------*/
2843 /* return typeof enum value */
2844 tree->type = EX_VALUE;
2847 if (IS_SPEC(tree->right->ftype)) {
2848 switch (SPEC_NOUN(tree->right->ftype)) {
2850 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2851 else typeofv = TYPEOF_INT;
2854 typeofv = TYPEOF_FLOAT;
2857 typeofv = TYPEOF_CHAR;
2860 typeofv = TYPEOF_VOID;
2863 typeofv = TYPEOF_STRUCT;
2866 typeofv = TYPEOF_BIT;
2869 typeofv = TYPEOF_SBIT;
2875 switch (DCL_TYPE(tree->right->ftype)) {
2877 typeofv = TYPEOF_POINTER;
2880 typeofv = TYPEOF_FPOINTER;
2883 typeofv = TYPEOF_CPOINTER;
2886 typeofv = TYPEOF_GPOINTER;
2889 typeofv = TYPEOF_PPOINTER;
2892 typeofv = TYPEOF_IPOINTER;
2895 typeofv = TYPEOF_ARRAY;
2898 typeofv = TYPEOF_FUNCTION;
2904 sprintf (buffer, "%d", typeofv);
2905 tree->opval.val = constVal (buffer);
2906 tree->right = tree->left = NULL;
2907 TETYPE (tree) = getSpec (TTYPE (tree) =
2908 tree->opval.val->type);
2911 /*------------------------------------------------------------------*/
2912 /*----------------------------*/
2913 /* conditional operator '?' */
2914 /*----------------------------*/
2916 /* the type is value of the colon operator (on the right) */
2917 assert(IS_COLON_OP(tree->right));
2918 /* if already known then replace the tree : optimizer will do it
2919 but faster to do it here */
2920 if (IS_LITERAL (LTYPE(tree))) {
2921 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2922 return decorateType(tree->right->left) ;
2924 return decorateType(tree->right->right) ;
2927 tree->right = decorateType(tree->right);
2928 TTYPE (tree) = RTYPE(tree);
2929 TETYPE (tree) = getSpec (TTYPE (tree));
2934 /* if they don't match we have a problem */
2935 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2937 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2938 goto errorTreeReturn;
2941 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2942 TETYPE (tree) = getSpec (TTYPE (tree));
2946 /*------------------------------------------------------------------*/
2947 /*----------------------------*/
2948 /* assignment operators */
2949 /*----------------------------*/
2952 /* for these it must be both must be integral */
2953 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2954 !IS_ARITHMETIC (RTYPE (tree)))
2956 werror (E_OPS_INTEGRAL);
2957 goto errorTreeReturn;
2960 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2962 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2963 werror (E_CODE_WRITE, " ");
2967 werror (E_LVALUE_REQUIRED, "*= or /=");
2968 goto errorTreeReturn;
2979 /* for these it must be both must be integral */
2980 if (!IS_INTEGRAL (LTYPE (tree)) ||
2981 !IS_INTEGRAL (RTYPE (tree)))
2983 werror (E_OPS_INTEGRAL);
2984 goto errorTreeReturn;
2987 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2989 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2990 werror (E_CODE_WRITE, " ");
2994 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2995 goto errorTreeReturn;
3001 /*------------------------------------------------------------------*/
3002 /*----------------------------*/
3004 /*----------------------------*/
3006 if (!(IS_PTR (LTYPE (tree)) ||
3007 IS_ARITHMETIC (LTYPE (tree))))
3009 werror (E_PLUS_INVALID, "-=");
3010 goto errorTreeReturn;
3013 if (!(IS_PTR (RTYPE (tree)) ||
3014 IS_ARITHMETIC (RTYPE (tree))))
3016 werror (E_PLUS_INVALID, "-=");
3017 goto errorTreeReturn;
3020 TETYPE (tree) = getSpec (TTYPE (tree) =
3021 computeType (LTYPE (tree),
3024 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3025 werror (E_CODE_WRITE, " ");
3029 werror (E_LVALUE_REQUIRED, "-=");
3030 goto errorTreeReturn;
3036 /*------------------------------------------------------------------*/
3037 /*----------------------------*/
3039 /*----------------------------*/
3041 /* this is not a unary operation */
3042 /* if both pointers then problem */
3043 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3045 werror (E_PTR_PLUS_PTR);
3046 goto errorTreeReturn;
3049 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3051 werror (E_PLUS_INVALID, "+=");
3052 goto errorTreeReturn;
3055 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3057 werror (E_PLUS_INVALID, "+=");
3058 goto errorTreeReturn;
3061 TETYPE (tree) = getSpec (TTYPE (tree) =
3062 computeType (LTYPE (tree),
3065 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3066 werror (E_CODE_WRITE, " ");
3070 werror (E_LVALUE_REQUIRED, "+=");
3071 goto errorTreeReturn;
3074 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3075 tree->opval.op = '=';
3079 /*------------------------------------------------------------------*/
3080 /*----------------------------*/
3081 /* straight assignemnt */
3082 /*----------------------------*/
3084 /* cannot be an aggregate */
3085 if (IS_AGGREGATE (LTYPE (tree)))
3087 werror (E_AGGR_ASSIGN);
3088 goto errorTreeReturn;
3091 /* they should either match or be castable */
3092 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3094 werror (E_TYPE_MISMATCH, "assignment", " ");
3095 fprintf (stderr, "type --> '");
3096 printTypeChain (RTYPE (tree), stderr);
3097 fprintf (stderr, "' ");
3098 fprintf (stderr, "assigned to type --> '");
3099 printTypeChain (LTYPE (tree), stderr);
3100 fprintf (stderr, "'\n");
3101 goto errorTreeReturn;
3104 /* if the left side of the tree is of type void
3105 then report error */
3106 if (IS_VOID (LTYPE (tree)))
3108 werror (E_CAST_ZERO);
3109 printFromToType(RTYPE(tree), LTYPE(tree));
3112 TETYPE (tree) = getSpec (TTYPE (tree) =
3116 if (!tree->initMode ) {
3117 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3118 werror (E_CODE_WRITE, " ");
3122 werror (E_LVALUE_REQUIRED, "=");
3123 goto errorTreeReturn;
3128 /*------------------------------------------------------------------*/
3129 /*----------------------------*/
3130 /* comma operator */
3131 /*----------------------------*/
3133 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3136 /*------------------------------------------------------------------*/
3137 /*----------------------------*/
3139 /*----------------------------*/
3143 if (processParms (tree->left,
3144 FUNC_ARGS(tree->left->ftype),
3145 tree->right, &parmNumber, TRUE)) {
3146 goto errorTreeReturn;
3149 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3150 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3152 //FUNC_ARGS(tree->left->ftype) =
3153 //reverseVal (FUNC_ARGS(tree->left->ftype));
3154 reverseParms (tree->right);
3157 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3160 /*------------------------------------------------------------------*/
3161 /*----------------------------*/
3162 /* return statement */
3163 /*----------------------------*/
3168 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3170 werror (W_RETURN_MISMATCH);
3171 printFromToType (RTYPE(tree), currFunc->type->next);
3172 goto errorTreeReturn;
3175 if (IS_VOID (currFunc->type->next)
3177 !IS_VOID (RTYPE (tree)))
3179 werror (E_FUNC_VOID);
3180 goto errorTreeReturn;
3183 /* if there is going to be a casing required then add it */
3184 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3187 decorateType (newNode (CAST,
3188 newAst_LINK (copyLinkChain (currFunc->type->next)),
3197 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3199 werror (E_VOID_FUNC, currFunc->name);
3200 goto errorTreeReturn;
3203 TTYPE (tree) = TETYPE (tree) = NULL;
3206 /*------------------------------------------------------------------*/
3207 /*----------------------------*/
3208 /* switch statement */
3209 /*----------------------------*/
3211 /* the switch value must be an integer */
3212 if (!IS_INTEGRAL (LTYPE (tree)))
3214 werror (E_SWITCH_NON_INTEGER);
3215 goto errorTreeReturn;
3218 TTYPE (tree) = TETYPE (tree) = NULL;
3221 /*------------------------------------------------------------------*/
3222 /*----------------------------*/
3224 /*----------------------------*/
3226 tree->left = backPatchLabels (tree->left,
3229 TTYPE (tree) = TETYPE (tree) = NULL;
3232 /*------------------------------------------------------------------*/
3233 /*----------------------------*/
3235 /*----------------------------*/
3238 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3239 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3240 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3242 /* if the for loop is reversible then
3243 reverse it otherwise do what we normally
3249 if (isLoopReversible (tree, &sym, &init, &end))
3250 return reverseLoop (tree, sym, init, end);
3252 return decorateType (createFor (AST_FOR (tree, trueLabel),
3253 AST_FOR (tree, continueLabel),
3254 AST_FOR (tree, falseLabel),
3255 AST_FOR (tree, condLabel),
3256 AST_FOR (tree, initExpr),
3257 AST_FOR (tree, condExpr),
3258 AST_FOR (tree, loopExpr),
3262 TTYPE (tree) = TETYPE (tree) = NULL;
3266 /* some error found this tree will be killed */
3268 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3269 tree->opval.op = NULLOP;
3275 /*-----------------------------------------------------------------*/
3276 /* sizeofOp - processes size of operation */
3277 /*-----------------------------------------------------------------*/
3279 sizeofOp (sym_link * type)
3283 /* make sure the type is complete and sane */
3284 checkTypeSanity(type, "(sizeof)");
3286 /* get the size and convert it to character */
3287 sprintf (buff, "%d", getSize (type));
3289 /* now convert into value */
3290 return constVal (buff);
3294 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3295 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3296 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3297 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3298 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3299 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3300 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3302 /*-----------------------------------------------------------------*/
3303 /* backPatchLabels - change and or not operators to flow control */
3304 /*-----------------------------------------------------------------*/
3306 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3312 if (!(IS_ANDORNOT (tree)))
3315 /* if this an and */
3318 static int localLbl = 0;
3321 sprintf (buffer, "_and_%d", localLbl++);
3322 localLabel = newSymbol (buffer, NestLevel);
3324 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3326 /* if left is already a IFX then just change the if true label in that */
3327 if (!IS_IFX (tree->left))
3328 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3330 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3331 /* right is a IFX then just join */
3332 if (IS_IFX (tree->right))
3333 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3335 tree->right = createLabel (localLabel, tree->right);
3336 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3338 return newNode (NULLOP, tree->left, tree->right);
3341 /* if this is an or operation */
3344 static int localLbl = 0;
3347 sprintf (buffer, "_or_%d", localLbl++);
3348 localLabel = newSymbol (buffer, NestLevel);
3350 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3352 /* if left is already a IFX then just change the if true label in that */
3353 if (!IS_IFX (tree->left))
3354 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3356 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3357 /* right is a IFX then just join */
3358 if (IS_IFX (tree->right))
3359 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3361 tree->right = createLabel (localLabel, tree->right);
3362 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3364 return newNode (NULLOP, tree->left, tree->right);
3370 int wasnot = IS_NOT (tree->left);
3371 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3373 /* if the left is already a IFX */
3374 if (!IS_IFX (tree->left))
3375 tree->left = newNode (IFX, tree->left, NULL);
3379 tree->left->trueLabel = trueLabel;
3380 tree->left->falseLabel = falseLabel;
3384 tree->left->trueLabel = falseLabel;
3385 tree->left->falseLabel = trueLabel;
3392 tree->trueLabel = trueLabel;
3393 tree->falseLabel = falseLabel;
3400 /*-----------------------------------------------------------------*/
3401 /* createBlock - create expression tree for block */
3402 /*-----------------------------------------------------------------*/
3404 createBlock (symbol * decl, ast * body)
3408 /* if the block has nothing */
3412 ex = newNode (BLOCK, NULL, body);
3413 ex->values.sym = decl;
3415 ex->right = ex->right;
3421 /*-----------------------------------------------------------------*/
3422 /* createLabel - creates the expression tree for labels */
3423 /*-----------------------------------------------------------------*/
3425 createLabel (symbol * label, ast * stmnt)
3428 char name[SDCC_NAME_MAX + 1];
3431 /* must create fresh symbol if the symbol name */
3432 /* exists in the symbol table, since there can */
3433 /* be a variable with the same name as the labl */
3434 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3435 (csym->level == label->level))
3436 label = newSymbol (label->name, label->level);
3438 /* change the name before putting it in add _ */
3439 sprintf (name, "%s", label->name);
3441 /* put the label in the LabelSymbol table */
3442 /* but first check if a label of the same */
3444 if ((csym = findSym (LabelTab, NULL, name)))
3445 werror (E_DUPLICATE_LABEL, label->name);
3447 addSym (LabelTab, label, name, label->level, 0, 0);
3450 label->key = labelKey++;
3451 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3457 /*-----------------------------------------------------------------*/
3458 /* createCase - generates the parsetree for a case statement */
3459 /*-----------------------------------------------------------------*/
3461 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3463 char caseLbl[SDCC_NAME_MAX + 1];
3467 /* if the switch statement does not exist */
3468 /* then case is out of context */
3471 werror (E_CASE_CONTEXT);
3475 caseVal = decorateType (resolveSymbols (caseVal));
3476 /* if not a constant then error */
3477 if (!IS_LITERAL (caseVal->ftype))
3479 werror (E_CASE_CONSTANT);
3483 /* if not a integer than error */
3484 if (!IS_INTEGRAL (caseVal->ftype))
3486 werror (E_CASE_NON_INTEGER);
3490 /* find the end of the switch values chain */
3491 if (!(val = swStat->values.switchVals.swVals))
3492 swStat->values.switchVals.swVals = caseVal->opval.val;
3495 /* also order the cases according to value */
3497 int cVal = (int) floatFromVal (caseVal->opval.val);
3498 while (val && (int) floatFromVal (val) < cVal)
3504 /* if we reached the end then */
3507 pval->next = caseVal->opval.val;
3511 /* we found a value greater than */
3512 /* the current value we must add this */
3513 /* before the value */
3514 caseVal->opval.val->next = val;
3516 /* if this was the first in chain */
3517 if (swStat->values.switchVals.swVals == val)
3518 swStat->values.switchVals.swVals =
3521 pval->next = caseVal->opval.val;
3526 /* create the case label */
3527 sprintf (caseLbl, "_case_%d_%d",
3528 swStat->values.switchVals.swNum,
3529 (int) floatFromVal (caseVal->opval.val));
3531 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3536 /*-----------------------------------------------------------------*/
3537 /* createDefault - creates the parse tree for the default statement */
3538 /*-----------------------------------------------------------------*/
3540 createDefault (ast * swStat, ast * stmnt)
3542 char defLbl[SDCC_NAME_MAX + 1];
3544 /* if the switch statement does not exist */
3545 /* then case is out of context */
3548 werror (E_CASE_CONTEXT);
3552 /* turn on the default flag */
3553 swStat->values.switchVals.swDefault = 1;
3555 /* create the label */
3556 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3557 return createLabel (newSymbol (defLbl, 0), stmnt);
3560 /*-----------------------------------------------------------------*/
3561 /* createIf - creates the parsetree for the if statement */
3562 /*-----------------------------------------------------------------*/
3564 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3566 static int Lblnum = 0;
3568 symbol *ifTrue, *ifFalse, *ifEnd;
3570 /* if neither exists */
3571 if (!elseBody && !ifBody) {
3572 // if there are no side effects (i++, j() etc)
3573 if (!hasSEFcalls(condAst)) {
3578 /* create the labels */
3579 sprintf (buffer, "_iffalse_%d", Lblnum);
3580 ifFalse = newSymbol (buffer, NestLevel);
3581 /* if no else body then end == false */
3586 sprintf (buffer, "_ifend_%d", Lblnum);
3587 ifEnd = newSymbol (buffer, NestLevel);
3590 sprintf (buffer, "_iftrue_%d", Lblnum);
3591 ifTrue = newSymbol (buffer, NestLevel);
3595 /* attach the ifTrue label to the top of it body */
3596 ifBody = createLabel (ifTrue, ifBody);
3597 /* attach a goto end to the ifBody if else is present */
3600 ifBody = newNode (NULLOP, ifBody,
3602 newAst_VALUE (symbolVal (ifEnd)),
3604 /* put the elseLabel on the else body */
3605 elseBody = createLabel (ifFalse, elseBody);
3606 /* out the end at the end of the body */
3607 elseBody = newNode (NULLOP,
3609 createLabel (ifEnd, NULL));
3613 ifBody = newNode (NULLOP, ifBody,
3614 createLabel (ifFalse, NULL));
3616 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3617 if (IS_IFX (condAst))
3620 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3622 return newNode (NULLOP, ifTree,
3623 newNode (NULLOP, ifBody, elseBody));
3627 /*-----------------------------------------------------------------*/
3628 /* createDo - creates parse tree for do */
3631 /* _docontinue_n: */
3632 /* condition_expression +-> trueLabel -> _dobody_n */
3634 /* +-> falseLabel-> _dobreak_n */
3636 /*-----------------------------------------------------------------*/
3638 createDo (symbol * trueLabel, symbol * continueLabel,
3639 symbol * falseLabel, ast * condAst, ast * doBody)
3644 /* if the body does not exist then it is simple */
3647 condAst = backPatchLabels (condAst, continueLabel, NULL);
3648 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3649 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3650 doTree->trueLabel = continueLabel;
3651 doTree->falseLabel = NULL;
3655 /* otherwise we have a body */
3656 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3658 /* attach the body label to the top */
3659 doBody = createLabel (trueLabel, doBody);
3660 /* attach the continue label to end of body */
3661 doBody = newNode (NULLOP, doBody,
3662 createLabel (continueLabel, NULL));
3664 /* now put the break label at the end */
3665 if (IS_IFX (condAst))
3668 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3670 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3672 /* putting it together */
3673 return newNode (NULLOP, doBody, doTree);
3676 /*-----------------------------------------------------------------*/
3677 /* createFor - creates parse tree for 'for' statement */
3680 /* condExpr +-> trueLabel -> _forbody_n */
3682 /* +-> falseLabel-> _forbreak_n */
3685 /* _forcontinue_n: */
3687 /* goto _forcond_n ; */
3689 /*-----------------------------------------------------------------*/
3691 createFor (symbol * trueLabel, symbol * continueLabel,
3692 symbol * falseLabel, symbol * condLabel,
3693 ast * initExpr, ast * condExpr, ast * loopExpr,
3698 /* if loopexpression not present then we can generate it */
3699 /* the same way as a while */
3701 return newNode (NULLOP, initExpr,
3702 createWhile (trueLabel, continueLabel,
3703 falseLabel, condExpr, forBody));
3704 /* vanilla for statement */
3705 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3707 if (condExpr && !IS_IFX (condExpr))
3708 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3711 /* attach condition label to condition */
3712 condExpr = createLabel (condLabel, condExpr);
3714 /* attach body label to body */
3715 forBody = createLabel (trueLabel, forBody);
3717 /* attach continue to forLoop expression & attach */
3718 /* goto the forcond @ and of loopExpression */
3719 loopExpr = createLabel (continueLabel,
3723 newAst_VALUE (symbolVal (condLabel)),
3725 /* now start putting them together */
3726 forTree = newNode (NULLOP, initExpr, condExpr);
3727 forTree = newNode (NULLOP, forTree, forBody);
3728 forTree = newNode (NULLOP, forTree, loopExpr);
3729 /* finally add the break label */
3730 forTree = newNode (NULLOP, forTree,
3731 createLabel (falseLabel, NULL));
3735 /*-----------------------------------------------------------------*/
3736 /* createWhile - creates parse tree for while statement */
3737 /* the while statement will be created as follows */
3739 /* _while_continue_n: */
3740 /* condition_expression +-> trueLabel -> _while_boby_n */
3742 /* +-> falseLabel -> _while_break_n */
3743 /* _while_body_n: */
3745 /* goto _while_continue_n */
3746 /* _while_break_n: */
3747 /*-----------------------------------------------------------------*/
3749 createWhile (symbol * trueLabel, symbol * continueLabel,
3750 symbol * falseLabel, ast * condExpr, ast * whileBody)
3754 /* put the continue label */
3755 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3756 condExpr = createLabel (continueLabel, condExpr);
3757 condExpr->lineno = 0;
3759 /* put the body label in front of the body */
3760 whileBody = createLabel (trueLabel, whileBody);
3761 whileBody->lineno = 0;
3762 /* put a jump to continue at the end of the body */
3763 /* and put break label at the end of the body */
3764 whileBody = newNode (NULLOP,
3767 newAst_VALUE (symbolVal (continueLabel)),
3768 createLabel (falseLabel, NULL)));
3770 /* put it all together */
3771 if (IS_IFX (condExpr))
3772 whileTree = condExpr;
3775 whileTree = newNode (IFX, condExpr, NULL);
3776 /* put the true & false labels in place */
3777 whileTree->trueLabel = trueLabel;
3778 whileTree->falseLabel = falseLabel;
3781 return newNode (NULLOP, whileTree, whileBody);
3784 /*-----------------------------------------------------------------*/
3785 /* optimizeGetHbit - get highest order bit of the expression */
3786 /*-----------------------------------------------------------------*/
3788 optimizeGetHbit (ast * tree)
3791 /* if this is not a bit and */
3792 if (!IS_BITAND (tree))
3795 /* will look for tree of the form
3796 ( expr >> ((sizeof expr) -1) ) & 1 */
3797 if (!IS_AST_LIT_VALUE (tree->right))
3800 if (AST_LIT_VALUE (tree->right) != 1)
3803 if (!IS_RIGHT_OP (tree->left))
3806 if (!IS_AST_LIT_VALUE (tree->left->right))
3809 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3810 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3813 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3817 /*-----------------------------------------------------------------*/
3818 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3819 /*-----------------------------------------------------------------*/
3821 optimizeRRCRLC (ast * root)
3823 /* will look for trees of the form
3824 (?expr << 1) | (?expr >> 7) or
3825 (?expr >> 7) | (?expr << 1) will make that
3826 into a RLC : operation ..
3828 (?expr >> 1) | (?expr << 7) or
3829 (?expr << 7) | (?expr >> 1) will make that
3830 into a RRC operation
3831 note : by 7 I mean (number of bits required to hold the
3833 /* if the root operations is not a | operation the not */
3834 if (!IS_BITOR (root))
3837 /* I have to think of a better way to match patterns this sucks */
3838 /* that aside let start looking for the first case : I use a the
3839 negative check a lot to improve the efficiency */
3840 /* (?expr << 1) | (?expr >> 7) */
3841 if (IS_LEFT_OP (root->left) &&
3842 IS_RIGHT_OP (root->right))
3845 if (!SPEC_USIGN (TETYPE (root->left->left)))
3848 if (!IS_AST_LIT_VALUE (root->left->right) ||
3849 !IS_AST_LIT_VALUE (root->right->right))
3852 /* make sure it is the same expression */
3853 if (!isAstEqual (root->left->left,
3857 if (AST_LIT_VALUE (root->left->right) != 1)
3860 if (AST_LIT_VALUE (root->right->right) !=
3861 (getSize (TTYPE (root->left->left)) * 8 - 1))
3864 /* whew got the first case : create the AST */
3865 return newNode (RLC, root->left->left, NULL);
3869 /* check for second case */
3870 /* (?expr >> 7) | (?expr << 1) */
3871 if (IS_LEFT_OP (root->right) &&
3872 IS_RIGHT_OP (root->left))
3875 if (!SPEC_USIGN (TETYPE (root->left->left)))
3878 if (!IS_AST_LIT_VALUE (root->left->right) ||
3879 !IS_AST_LIT_VALUE (root->right->right))
3882 /* make sure it is the same symbol */
3883 if (!isAstEqual (root->left->left,
3887 if (AST_LIT_VALUE (root->right->right) != 1)
3890 if (AST_LIT_VALUE (root->left->right) !=
3891 (getSize (TTYPE (root->left->left)) * 8 - 1))
3894 /* whew got the first case : create the AST */
3895 return newNode (RLC, root->left->left, NULL);
3900 /* third case for RRC */
3901 /* (?symbol >> 1) | (?symbol << 7) */
3902 if (IS_LEFT_OP (root->right) &&
3903 IS_RIGHT_OP (root->left))
3906 if (!SPEC_USIGN (TETYPE (root->left->left)))
3909 if (!IS_AST_LIT_VALUE (root->left->right) ||
3910 !IS_AST_LIT_VALUE (root->right->right))
3913 /* make sure it is the same symbol */
3914 if (!isAstEqual (root->left->left,
3918 if (AST_LIT_VALUE (root->left->right) != 1)
3921 if (AST_LIT_VALUE (root->right->right) !=
3922 (getSize (TTYPE (root->left->left)) * 8 - 1))
3925 /* whew got the first case : create the AST */
3926 return newNode (RRC, root->left->left, NULL);
3930 /* fourth and last case for now */
3931 /* (?symbol << 7) | (?symbol >> 1) */
3932 if (IS_RIGHT_OP (root->right) &&
3933 IS_LEFT_OP (root->left))
3936 if (!SPEC_USIGN (TETYPE (root->left->left)))
3939 if (!IS_AST_LIT_VALUE (root->left->right) ||
3940 !IS_AST_LIT_VALUE (root->right->right))
3943 /* make sure it is the same symbol */
3944 if (!isAstEqual (root->left->left,
3948 if (AST_LIT_VALUE (root->right->right) != 1)
3951 if (AST_LIT_VALUE (root->left->right) !=
3952 (getSize (TTYPE (root->left->left)) * 8 - 1))
3955 /* whew got the first case : create the AST */
3956 return newNode (RRC, root->left->left, NULL);
3960 /* not found return root */
3964 /*-----------------------------------------------------------------*/
3965 /* optimizeCompare - otimizes compares for bit variables */
3966 /*-----------------------------------------------------------------*/
3968 optimizeCompare (ast * root)
3970 ast *optExpr = NULL;
3973 unsigned int litValue;
3975 /* if nothing then return nothing */
3979 /* if not a compare op then do leaves */
3980 if (!IS_COMPARE_OP (root))
3982 root->left = optimizeCompare (root->left);
3983 root->right = optimizeCompare (root->right);
3987 /* if left & right are the same then depending
3988 of the operation do */
3989 if (isAstEqual (root->left, root->right))
3991 switch (root->opval.op)
3996 optExpr = newAst_VALUE (constVal ("0"));
4001 optExpr = newAst_VALUE (constVal ("1"));
4005 return decorateType (optExpr);
4008 vleft = (root->left->type == EX_VALUE ?
4009 root->left->opval.val : NULL);
4011 vright = (root->right->type == EX_VALUE ?
4012 root->right->opval.val : NULL);
4014 /* if left is a BITVAR in BITSPACE */
4015 /* and right is a LITERAL then opt- */
4016 /* imize else do nothing */
4017 if (vleft && vright &&
4018 IS_BITVAR (vleft->etype) &&
4019 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4020 IS_LITERAL (vright->etype))
4023 /* if right side > 1 then comparison may never succeed */
4024 if ((litValue = (int) floatFromVal (vright)) > 1)
4026 werror (W_BAD_COMPARE);
4032 switch (root->opval.op)
4034 case '>': /* bit value greater than 1 cannot be */
4035 werror (W_BAD_COMPARE);
4039 case '<': /* bit value < 1 means 0 */
4041 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4044 case LE_OP: /* bit value <= 1 means no check */
4045 optExpr = newAst_VALUE (vright);
4048 case GE_OP: /* bit value >= 1 means only check for = */
4050 optExpr = newAst_VALUE (vleft);
4055 { /* literal is zero */
4056 switch (root->opval.op)
4058 case '<': /* bit value < 0 cannot be */
4059 werror (W_BAD_COMPARE);
4063 case '>': /* bit value > 0 means 1 */
4065 optExpr = newAst_VALUE (vleft);
4068 case LE_OP: /* bit value <= 0 means no check */
4069 case GE_OP: /* bit value >= 0 means no check */
4070 werror (W_BAD_COMPARE);
4074 case EQ_OP: /* bit == 0 means ! of bit */
4075 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4079 return decorateType (resolveSymbols (optExpr));
4080 } /* end-of-if of BITVAR */
4085 /*-----------------------------------------------------------------*/
4086 /* addSymToBlock : adds the symbol to the first block we find */
4087 /*-----------------------------------------------------------------*/
4089 addSymToBlock (symbol * sym, ast * tree)
4091 /* reached end of tree or a leaf */
4092 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4096 if (IS_AST_OP (tree) &&
4097 tree->opval.op == BLOCK)
4100 symbol *lsym = copySymbol (sym);
4102 lsym->next = AST_VALUES (tree, sym);
4103 AST_VALUES (tree, sym) = lsym;
4107 addSymToBlock (sym, tree->left);
4108 addSymToBlock (sym, tree->right);
4111 /*-----------------------------------------------------------------*/
4112 /* processRegParms - do processing for register parameters */
4113 /*-----------------------------------------------------------------*/
4115 processRegParms (value * args, ast * body)
4119 if (IS_REGPARM (args->etype))
4120 addSymToBlock (args->sym, body);
4125 /*-----------------------------------------------------------------*/
4126 /* resetParmKey - resets the operandkeys for the symbols */
4127 /*-----------------------------------------------------------------*/
4128 DEFSETFUNC (resetParmKey)
4139 /*-----------------------------------------------------------------*/
4140 /* createFunction - This is the key node that calls the iCode for */
4141 /* generating the code for a function. Note code */
4142 /* is generated function by function, later when */
4143 /* add inter-procedural analysis this will change */
4144 /*-----------------------------------------------------------------*/
4146 createFunction (symbol * name, ast * body)
4152 iCode *piCode = NULL;
4154 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4155 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4157 /* if check function return 0 then some problem */
4158 if (checkFunction (name, NULL) == 0)
4161 /* create a dummy block if none exists */
4163 body = newNode (BLOCK, NULL, NULL);
4167 /* check if the function name already in the symbol table */
4168 if ((csym = findSym (SymbolTab, NULL, name->name)))
4171 /* special case for compiler defined functions
4172 we need to add the name to the publics list : this
4173 actually means we are now compiling the compiler
4177 addSet (&publics, name);
4183 allocVariables (name);
4185 name->lastLine = yylineno;
4188 /* set the stack pointer */
4189 /* PENDING: check this for the mcs51 */
4190 stackPtr = -port->stack.direction * port->stack.call_overhead;
4191 if (IFFUNC_ISISR (name->type))
4192 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4193 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4194 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4196 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4198 fetype = getSpec (name->type); /* get the specifier for the function */
4199 /* if this is a reentrant function then */
4200 if (IFFUNC_ISREENT (name->type))
4203 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4205 /* do processing for parameters that are passed in registers */
4206 processRegParms (FUNC_ARGS(name->type), body);
4208 /* set the stack pointer */
4212 /* allocate & autoinit the block variables */
4213 processBlockVars (body, &stack, ALLOCATE);
4215 /* save the stack information */
4216 if (options.useXstack)
4217 name->xstack = SPEC_STAK (fetype) = stack;
4219 name->stack = SPEC_STAK (fetype) = stack;
4221 /* name needs to be mangled */
4222 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4224 body = resolveSymbols (body); /* resolve the symbols */
4225 body = decorateType (body); /* propagateType & do semantic checks */
4227 ex = newAst_VALUE (symbolVal (name)); /* create name */
4228 ex = newNode (FUNCTION, ex, body);
4229 ex->values.args = FUNC_ARGS(name->type);
4231 if (options.dump_tree) PA(ex);
4234 werror (E_FUNC_NO_CODE, name->name);
4238 /* create the node & generate intermediate code */
4240 codeOutFile = code->oFile;
4241 piCode = iCodeFromAst (ex);
4245 werror (E_FUNC_NO_CODE, name->name);
4249 eBBlockFromiCode (piCode);
4251 /* if there are any statics then do them */
4254 GcurMemmap = statsg;
4255 codeOutFile = statsg->oFile;
4256 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4262 /* dealloc the block variables */
4263 processBlockVars (body, &stack, DEALLOCATE);
4264 /* deallocate paramaters */
4265 deallocParms (FUNC_ARGS(name->type));
4267 if (IFFUNC_ISREENT (name->type))
4270 /* we are done freeup memory & cleanup */
4272 if (port->reset_labelKey) labelKey = 1;
4274 FUNC_HASBODY(name->type) = 1;
4275 addSet (&operKeyReset, name);
4276 applyToSet (operKeyReset, resetParmKey);
4279 cdbStructBlock (1, cdbFile);
4281 cleanUpLevel (LabelTab, 0);
4282 cleanUpBlock (StructTab, 1);
4283 cleanUpBlock (TypedefTab, 1);
4285 xstack->syms = NULL;
4286 istack->syms = NULL;
4291 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4292 /*-----------------------------------------------------------------*/
4293 /* ast_print : prints the ast (for debugging purposes) */
4294 /*-----------------------------------------------------------------*/
4296 void ast_print (ast * tree, FILE *outfile, int indent)
4301 /* can print only decorated trees */
4302 if (!tree->decorated) return;
4304 /* if any child is an error | this one is an error do nothing */
4305 if (tree->isError ||
4306 (tree->left && tree->left->isError) ||
4307 (tree->right && tree->right->isError)) {
4308 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4312 /* print the line */
4313 /* if not block & function */
4314 if (tree->type == EX_OP &&
4315 (tree->opval.op != FUNCTION &&
4316 tree->opval.op != BLOCK &&
4317 tree->opval.op != NULLOP)) {
4320 if (tree->opval.op == FUNCTION) {
4322 value *args=FUNC_ARGS(tree->left->opval.val->type);
4323 fprintf(outfile,"FUNCTION (%s=%p) type (",
4324 tree->left->opval.val->name, tree);
4325 printTypeChain (tree->ftype,outfile);
4326 fprintf(outfile,") args (");
4329 fprintf (outfile, ", ");
4331 printTypeChain (args ? args->type : NULL, outfile);
4333 args= args ? args->next : NULL;
4335 fprintf(outfile,")\n");
4336 ast_print(tree->left,outfile,indent);
4337 ast_print(tree->right,outfile,indent);
4340 if (tree->opval.op == BLOCK) {
4341 symbol *decls = tree->values.sym;
4342 INDENT(indent,outfile);
4343 fprintf(outfile,"{\n");
4345 INDENT(indent+2,outfile);
4346 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4347 decls->name, decls);
4348 printTypeChain(decls->type,outfile);
4349 fprintf(outfile,")\n");
4351 decls = decls->next;
4353 ast_print(tree->right,outfile,indent+2);
4354 INDENT(indent,outfile);
4355 fprintf(outfile,"}\n");
4358 if (tree->opval.op == NULLOP) {
4359 fprintf(outfile,"\n");
4360 ast_print(tree->left,outfile,indent);
4361 fprintf(outfile,"\n");
4362 ast_print(tree->right,outfile,indent);
4365 INDENT(indent,outfile);
4367 /*------------------------------------------------------------------*/
4368 /*----------------------------*/
4369 /* leaf has been reached */
4370 /*----------------------------*/
4371 /* if this is of type value */
4372 /* just get the type */
4373 if (tree->type == EX_VALUE) {
4375 if (IS_LITERAL (tree->opval.val->etype)) {
4376 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4377 (int) floatFromVal(tree->opval.val),
4378 (int) floatFromVal(tree->opval.val),
4379 floatFromVal(tree->opval.val));
4380 } else if (tree->opval.val->sym) {
4381 /* if the undefined flag is set then give error message */
4382 if (tree->opval.val->sym->undefined) {
4383 fprintf(outfile,"UNDEFINED SYMBOL ");
4385 fprintf(outfile,"SYMBOL ");
4387 fprintf(outfile,"(%s=%p)",
4388 tree->opval.val->sym->name,tree);
4391 fprintf(outfile," type (");
4392 printTypeChain(tree->ftype,outfile);
4393 fprintf(outfile,")\n");
4395 fprintf(outfile,"\n");
4400 /* if type link for the case of cast */
4401 if (tree->type == EX_LINK) {
4402 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4403 printTypeChain(tree->opval.lnk,outfile);
4404 fprintf(outfile,")\n");
4409 /* depending on type of operator do */
4411 switch (tree->opval.op) {
4412 /*------------------------------------------------------------------*/
4413 /*----------------------------*/
4415 /*----------------------------*/
4417 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4418 printTypeChain(tree->ftype,outfile);
4419 fprintf(outfile,")\n");
4420 ast_print(tree->left,outfile,indent+2);
4421 ast_print(tree->right,outfile,indent+2);
4424 /*------------------------------------------------------------------*/
4425 /*----------------------------*/
4427 /*----------------------------*/
4429 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4430 printTypeChain(tree->ftype,outfile);
4431 fprintf(outfile,")\n");
4432 ast_print(tree->left,outfile,indent+2);
4433 ast_print(tree->right,outfile,indent+2);
4436 /*------------------------------------------------------------------*/
4437 /*----------------------------*/
4438 /* struct/union pointer */
4439 /*----------------------------*/
4441 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4442 printTypeChain(tree->ftype,outfile);
4443 fprintf(outfile,")\n");
4444 ast_print(tree->left,outfile,indent+2);
4445 ast_print(tree->right,outfile,indent+2);
4448 /*------------------------------------------------------------------*/
4449 /*----------------------------*/
4450 /* ++/-- operation */
4451 /*----------------------------*/
4452 case INC_OP: /* incerement operator unary so left only */
4453 fprintf(outfile,"INC_OP (%p) type (",tree);
4454 printTypeChain(tree->ftype,outfile);
4455 fprintf(outfile,")\n");
4456 ast_print(tree->left,outfile,indent+2);
4460 fprintf(outfile,"DEC_OP (%p) type (",tree);
4461 printTypeChain(tree->ftype,outfile);
4462 fprintf(outfile,")\n");
4463 ast_print(tree->left,outfile,indent+2);
4466 /*------------------------------------------------------------------*/
4467 /*----------------------------*/
4469 /*----------------------------*/
4472 fprintf(outfile,"& (%p) type (",tree);
4473 printTypeChain(tree->ftype,outfile);
4474 fprintf(outfile,")\n");
4475 ast_print(tree->left,outfile,indent+2);
4476 ast_print(tree->right,outfile,indent+2);
4478 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4479 printTypeChain(tree->ftype,outfile);
4480 fprintf(outfile,")\n");
4481 ast_print(tree->left,outfile,indent+2);
4482 ast_print(tree->right,outfile,indent+2);
4485 /*----------------------------*/
4487 /*----------------------------*/
4489 fprintf(outfile,"OR (%p) type (",tree);
4490 printTypeChain(tree->ftype,outfile);
4491 fprintf(outfile,")\n");
4492 ast_print(tree->left,outfile,indent+2);
4493 ast_print(tree->right,outfile,indent+2);
4495 /*------------------------------------------------------------------*/
4496 /*----------------------------*/
4498 /*----------------------------*/
4500 fprintf(outfile,"XOR (%p) type (",tree);
4501 printTypeChain(tree->ftype,outfile);
4502 fprintf(outfile,")\n");
4503 ast_print(tree->left,outfile,indent+2);
4504 ast_print(tree->right,outfile,indent+2);
4507 /*------------------------------------------------------------------*/
4508 /*----------------------------*/
4510 /*----------------------------*/
4512 fprintf(outfile,"DIV (%p) type (",tree);
4513 printTypeChain(tree->ftype,outfile);
4514 fprintf(outfile,")\n");
4515 ast_print(tree->left,outfile,indent+2);
4516 ast_print(tree->right,outfile,indent+2);
4518 /*------------------------------------------------------------------*/
4519 /*----------------------------*/
4521 /*----------------------------*/
4523 fprintf(outfile,"MOD (%p) type (",tree);
4524 printTypeChain(tree->ftype,outfile);
4525 fprintf(outfile,")\n");
4526 ast_print(tree->left,outfile,indent+2);
4527 ast_print(tree->right,outfile,indent+2);
4530 /*------------------------------------------------------------------*/
4531 /*----------------------------*/
4532 /* address dereference */
4533 /*----------------------------*/
4534 case '*': /* can be unary : if right is null then unary operation */
4536 fprintf(outfile,"DEREF (%p) type (",tree);
4537 printTypeChain(tree->ftype,outfile);
4538 fprintf(outfile,")\n");
4539 ast_print(tree->left,outfile,indent+2);
4542 /*------------------------------------------------------------------*/
4543 /*----------------------------*/
4544 /* multiplication */
4545 /*----------------------------*/
4546 fprintf(outfile,"MULT (%p) type (",tree);
4547 printTypeChain(tree->ftype,outfile);
4548 fprintf(outfile,")\n");
4549 ast_print(tree->left,outfile,indent+2);
4550 ast_print(tree->right,outfile,indent+2);
4554 /*------------------------------------------------------------------*/
4555 /*----------------------------*/
4556 /* unary '+' operator */
4557 /*----------------------------*/
4561 fprintf(outfile,"UPLUS (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+2);
4566 /*------------------------------------------------------------------*/
4567 /*----------------------------*/
4569 /*----------------------------*/
4570 fprintf(outfile,"ADD (%p) type (",tree);
4571 printTypeChain(tree->ftype,outfile);
4572 fprintf(outfile,")\n");
4573 ast_print(tree->left,outfile,indent+2);
4574 ast_print(tree->right,outfile,indent+2);
4577 /*------------------------------------------------------------------*/
4578 /*----------------------------*/
4580 /*----------------------------*/
4581 case '-': /* can be unary */
4583 fprintf(outfile,"UMINUS (%p) type (",tree);
4584 printTypeChain(tree->ftype,outfile);
4585 fprintf(outfile,")\n");
4586 ast_print(tree->left,outfile,indent+2);
4588 /*------------------------------------------------------------------*/
4589 /*----------------------------*/
4591 /*----------------------------*/
4592 fprintf(outfile,"SUB (%p) type (",tree);
4593 printTypeChain(tree->ftype,outfile);
4594 fprintf(outfile,")\n");
4595 ast_print(tree->left,outfile,indent+2);
4596 ast_print(tree->right,outfile,indent+2);
4599 /*------------------------------------------------------------------*/
4600 /*----------------------------*/
4602 /*----------------------------*/
4604 fprintf(outfile,"COMPL (%p) type (",tree);
4605 printTypeChain(tree->ftype,outfile);
4606 fprintf(outfile,")\n");
4607 ast_print(tree->left,outfile,indent+2);
4609 /*------------------------------------------------------------------*/
4610 /*----------------------------*/
4612 /*----------------------------*/
4614 fprintf(outfile,"NOT (%p) type (",tree);
4615 printTypeChain(tree->ftype,outfile);
4616 fprintf(outfile,")\n");
4617 ast_print(tree->left,outfile,indent+2);
4619 /*------------------------------------------------------------------*/
4620 /*----------------------------*/
4622 /*----------------------------*/
4624 fprintf(outfile,"RRC (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+2);
4631 fprintf(outfile,"RLC (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+2);
4637 fprintf(outfile,"GETHBIT (%p) type (",tree);
4638 printTypeChain(tree->ftype,outfile);
4639 fprintf(outfile,")\n");
4640 ast_print(tree->left,outfile,indent+2);
4643 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4644 printTypeChain(tree->ftype,outfile);
4645 fprintf(outfile,")\n");
4646 ast_print(tree->left,outfile,indent+2);
4647 ast_print(tree->right,outfile,indent+2);
4650 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+2);
4654 ast_print(tree->right,outfile,indent+2);
4656 /*------------------------------------------------------------------*/
4657 /*----------------------------*/
4659 /*----------------------------*/
4660 case CAST: /* change the type */
4661 fprintf(outfile,"CAST (%p) from type (",tree);
4662 printTypeChain(tree->right->ftype,outfile);
4663 fprintf(outfile,") to type (");
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->right,outfile,indent+2);
4670 fprintf(outfile,"ANDAND (%p) type (",tree);
4671 printTypeChain(tree->ftype,outfile);
4672 fprintf(outfile,")\n");
4673 ast_print(tree->left,outfile,indent+2);
4674 ast_print(tree->right,outfile,indent+2);
4677 fprintf(outfile,"OROR (%p) type (",tree);
4678 printTypeChain(tree->ftype,outfile);
4679 fprintf(outfile,")\n");
4680 ast_print(tree->left,outfile,indent+2);
4681 ast_print(tree->right,outfile,indent+2);
4684 /*------------------------------------------------------------------*/
4685 /*----------------------------*/
4686 /* comparison operators */
4687 /*----------------------------*/
4689 fprintf(outfile,"GT(>) (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+2);
4693 ast_print(tree->right,outfile,indent+2);
4696 fprintf(outfile,"LT(<) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+2);
4700 ast_print(tree->right,outfile,indent+2);
4703 fprintf(outfile,"LE(<=) (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+2);
4707 ast_print(tree->right,outfile,indent+2);
4710 fprintf(outfile,"GE(>=) (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+2);
4714 ast_print(tree->right,outfile,indent+2);
4717 fprintf(outfile,"EQ(==) (%p) type (",tree);
4718 printTypeChain(tree->ftype,outfile);
4719 fprintf(outfile,")\n");
4720 ast_print(tree->left,outfile,indent+2);
4721 ast_print(tree->right,outfile,indent+2);
4724 fprintf(outfile,"NE(!=) (%p) type (",tree);
4725 printTypeChain(tree->ftype,outfile);
4726 fprintf(outfile,")\n");
4727 ast_print(tree->left,outfile,indent+2);
4728 ast_print(tree->right,outfile,indent+2);
4729 /*------------------------------------------------------------------*/
4730 /*----------------------------*/
4732 /*----------------------------*/
4733 case SIZEOF: /* evaluate wihout code generation */
4734 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4737 /*------------------------------------------------------------------*/
4738 /*----------------------------*/
4739 /* conditional operator '?' */
4740 /*----------------------------*/
4742 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4743 printTypeChain(tree->ftype,outfile);
4744 fprintf(outfile,")\n");
4745 ast_print(tree->left,outfile,indent+2);
4746 ast_print(tree->right,outfile,indent+2);
4750 fprintf(outfile,"COLON(:) (%p) type (",tree);
4751 printTypeChain(tree->ftype,outfile);
4752 fprintf(outfile,")\n");
4753 ast_print(tree->left,outfile,indent+2);
4754 ast_print(tree->right,outfile,indent+2);
4757 /*------------------------------------------------------------------*/
4758 /*----------------------------*/
4759 /* assignment operators */
4760 /*----------------------------*/
4762 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4763 printTypeChain(tree->ftype,outfile);
4764 fprintf(outfile,")\n");
4765 ast_print(tree->left,outfile,indent+2);
4766 ast_print(tree->right,outfile,indent+2);
4769 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+2);
4773 ast_print(tree->right,outfile,indent+2);
4776 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+2);
4780 ast_print(tree->right,outfile,indent+2);
4783 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4784 printTypeChain(tree->ftype,outfile);
4785 fprintf(outfile,")\n");
4786 ast_print(tree->left,outfile,indent+2);
4787 ast_print(tree->right,outfile,indent+2);
4790 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4791 printTypeChain(tree->ftype,outfile);
4792 fprintf(outfile,")\n");
4793 ast_print(tree->left,outfile,indent+2);
4794 ast_print(tree->right,outfile,indent+2);
4797 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4798 printTypeChain(tree->ftype,outfile);
4799 fprintf(outfile,")\n");
4800 ast_print(tree->left,outfile,indent+2);
4801 ast_print(tree->right,outfile,indent+2);
4804 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4805 printTypeChain(tree->ftype,outfile);
4806 fprintf(outfile,")\n");
4807 ast_print(tree->left,outfile,indent+2);
4808 ast_print(tree->right,outfile,indent+2);
4810 /*------------------------------------------------------------------*/
4811 /*----------------------------*/
4813 /*----------------------------*/
4815 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4816 printTypeChain(tree->ftype,outfile);
4817 fprintf(outfile,")\n");
4818 ast_print(tree->left,outfile,indent+2);
4819 ast_print(tree->right,outfile,indent+2);
4821 /*------------------------------------------------------------------*/
4822 /*----------------------------*/
4824 /*----------------------------*/
4826 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4827 printTypeChain(tree->ftype,outfile);
4828 fprintf(outfile,")\n");
4829 ast_print(tree->left,outfile,indent+2);
4830 ast_print(tree->right,outfile,indent+2);
4832 /*------------------------------------------------------------------*/
4833 /*----------------------------*/
4834 /* straight assignemnt */
4835 /*----------------------------*/
4837 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4838 printTypeChain(tree->ftype,outfile);
4839 fprintf(outfile,")\n");
4840 ast_print(tree->left,outfile,indent+2);
4841 ast_print(tree->right,outfile,indent+2);
4843 /*------------------------------------------------------------------*/
4844 /*----------------------------*/
4845 /* comma operator */
4846 /*----------------------------*/
4848 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4849 printTypeChain(tree->ftype,outfile);
4850 fprintf(outfile,")\n");
4851 ast_print(tree->left,outfile,indent+2);
4852 ast_print(tree->right,outfile,indent+2);
4854 /*------------------------------------------------------------------*/
4855 /*----------------------------*/
4857 /*----------------------------*/
4860 fprintf(outfile,"CALL (%p) type (",tree);
4861 printTypeChain(tree->ftype,outfile);
4862 fprintf(outfile,")\n");
4863 ast_print(tree->left,outfile,indent+2);
4864 ast_print(tree->right,outfile,indent+2);
4867 fprintf(outfile,"PARMS\n");
4868 ast_print(tree->left,outfile,indent+2);
4869 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4870 ast_print(tree->right,outfile,indent+2);
4873 /*------------------------------------------------------------------*/
4874 /*----------------------------*/
4875 /* return statement */
4876 /*----------------------------*/
4878 fprintf(outfile,"RETURN (%p) type (",tree);
4879 printTypeChain(tree->right->ftype,outfile);
4880 fprintf(outfile,")\n");
4881 ast_print(tree->right,outfile,indent+2);
4883 /*------------------------------------------------------------------*/
4884 /*----------------------------*/
4885 /* label statement */
4886 /*----------------------------*/
4888 fprintf(outfile,"LABEL (%p)\n",tree);
4889 ast_print(tree->left,outfile,indent+2);
4890 ast_print(tree->right,outfile,indent);
4892 /*------------------------------------------------------------------*/
4893 /*----------------------------*/
4894 /* switch statement */
4895 /*----------------------------*/
4899 fprintf(outfile,"SWITCH (%p) ",tree);
4900 ast_print(tree->left,outfile,0);
4901 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4902 INDENT(indent+2,outfile);
4903 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4904 (int) floatFromVal(val),
4905 tree->values.switchVals.swNum,
4906 (int) floatFromVal(val));
4908 ast_print(tree->right,outfile,indent);
4911 /*------------------------------------------------------------------*/
4912 /*----------------------------*/
4914 /*----------------------------*/
4916 fprintf(outfile,"IF (%p) \n",tree);
4917 ast_print(tree->left,outfile,indent+2);
4918 if (tree->trueLabel) {
4919 INDENT(indent,outfile);
4920 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4922 if (tree->falseLabel) {
4923 INDENT(indent,outfile);
4924 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4926 ast_print(tree->right,outfile,indent+2);
4928 /*------------------------------------------------------------------*/
4929 /*----------------------------*/
4931 /*----------------------------*/
4933 fprintf(outfile,"FOR (%p) \n",tree);
4934 if (AST_FOR( tree, initExpr)) {
4935 INDENT(indent+2,outfile);
4936 fprintf(outfile,"INIT EXPR ");
4937 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4939 if (AST_FOR( tree, condExpr)) {
4940 INDENT(indent+2,outfile);
4941 fprintf(outfile,"COND EXPR ");
4942 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4944 if (AST_FOR( tree, loopExpr)) {
4945 INDENT(indent+2,outfile);
4946 fprintf(outfile,"LOOP EXPR ");
4947 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4949 fprintf(outfile,"FOR LOOP BODY \n");
4950 ast_print(tree->left,outfile,indent+2);
4959 ast_print(t,stdout,0);