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
1175 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1176 "unexpected link in expression tree\n");
1179 if (cexpr->opval.op==ARRAYINIT) {
1180 // this is a list of literals
1183 if (cexpr->opval.op=='=') {
1184 return constExprTree(cexpr->right);
1186 if (cexpr->opval.op==CAST) {
1187 // jwk: cast ignored, maybe we should throw a warning here
1188 return constExprTree(cexpr->right);
1190 if (cexpr->opval.op=='&') {
1193 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1196 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1203 /*-----------------------------------------------------------------*/
1204 /* constExprValue - returns the value of a constant expression */
1205 /* or NULL if it is not a constant expression */
1206 /*-----------------------------------------------------------------*/
1208 constExprValue (ast * cexpr, int check)
1210 cexpr = decorateType (resolveSymbols (cexpr));
1212 /* if this is not a constant then */
1213 if (!IS_LITERAL (cexpr->ftype))
1215 /* then check if this is a literal array
1217 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1218 SPEC_CVAL (cexpr->etype).v_char &&
1219 IS_ARRAY (cexpr->ftype))
1221 value *val = valFromType (cexpr->ftype);
1222 SPEC_SCLS (val->etype) = S_LITERAL;
1223 val->sym = cexpr->opval.val->sym;
1224 val->sym->type = copyLinkChain (cexpr->ftype);
1225 val->sym->etype = getSpec (val->sym->type);
1226 strcpy (val->name, cexpr->opval.val->sym->rname);
1230 /* if we are casting a literal value then */
1231 if (IS_AST_OP (cexpr) &&
1232 cexpr->opval.op == CAST &&
1233 IS_LITERAL (cexpr->left->ftype))
1234 return valCastLiteral (cexpr->ftype,
1235 floatFromVal (cexpr->left->opval.val));
1237 if (IS_AST_VALUE (cexpr))
1238 return cexpr->opval.val;
1241 werror (E_CONST_EXPECTED, "found expression");
1246 /* return the value */
1247 return cexpr->opval.val;
1251 /*-----------------------------------------------------------------*/
1252 /* isLabelInAst - will return true if a given label is found */
1253 /*-----------------------------------------------------------------*/
1255 isLabelInAst (symbol * label, ast * tree)
1257 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1260 if (IS_AST_OP (tree) &&
1261 tree->opval.op == LABEL &&
1262 isSymbolEqual (AST_SYMBOL (tree->left), label))
1265 return isLabelInAst (label, tree->right) &&
1266 isLabelInAst (label, tree->left);
1270 /*-----------------------------------------------------------------*/
1271 /* isLoopCountable - return true if the loop count can be determi- */
1272 /* -ned at compile time . */
1273 /*-----------------------------------------------------------------*/
1275 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1276 symbol ** sym, ast ** init, ast ** end)
1279 /* the loop is considered countable if the following
1280 conditions are true :-
1282 a) initExpr :- <sym> = <const>
1283 b) condExpr :- <sym> < <const1>
1284 c) loopExpr :- <sym> ++
1287 /* first check the initExpr */
1288 if (IS_AST_OP (initExpr) &&
1289 initExpr->opval.op == '=' && /* is assignment */
1290 IS_AST_SYM_VALUE (initExpr->left))
1291 { /* left is a symbol */
1293 *sym = AST_SYMBOL (initExpr->left);
1294 *init = initExpr->right;
1299 /* for now the symbol has to be of
1301 if (!IS_INTEGRAL ((*sym)->type))
1304 /* now check condExpr */
1305 if (IS_AST_OP (condExpr))
1308 switch (condExpr->opval.op)
1311 if (IS_AST_SYM_VALUE (condExpr->left) &&
1312 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1313 IS_AST_LIT_VALUE (condExpr->right))
1315 *end = condExpr->right;
1321 if (IS_AST_OP (condExpr->left) &&
1322 condExpr->left->opval.op == '>' &&
1323 IS_AST_LIT_VALUE (condExpr->left->right) &&
1324 IS_AST_SYM_VALUE (condExpr->left->left) &&
1325 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1328 *end = newNode ('+', condExpr->left->right,
1329 newAst_VALUE (constVal ("1")));
1340 /* check loop expression is of the form <sym>++ */
1341 if (!IS_AST_OP (loopExpr))
1344 /* check if <sym> ++ */
1345 if (loopExpr->opval.op == INC_OP)
1351 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1352 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1359 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1360 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1368 if (loopExpr->opval.op == ADD_ASSIGN)
1371 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1372 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1373 IS_AST_LIT_VALUE (loopExpr->right) &&
1374 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1382 /*-----------------------------------------------------------------*/
1383 /* astHasVolatile - returns true if ast contains any volatile */
1384 /*-----------------------------------------------------------------*/
1386 astHasVolatile (ast * tree)
1391 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1394 if (IS_AST_OP (tree))
1395 return astHasVolatile (tree->left) ||
1396 astHasVolatile (tree->right);
1401 /*-----------------------------------------------------------------*/
1402 /* astHasPointer - return true if the ast contains any ptr variable */
1403 /*-----------------------------------------------------------------*/
1405 astHasPointer (ast * tree)
1410 if (IS_AST_LINK (tree))
1413 /* if we hit an array expression then check
1414 only the left side */
1415 if (IS_AST_OP (tree) && tree->opval.op == '[')
1416 return astHasPointer (tree->left);
1418 if (IS_AST_VALUE (tree))
1419 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1421 return astHasPointer (tree->left) ||
1422 astHasPointer (tree->right);
1426 /*-----------------------------------------------------------------*/
1427 /* astHasSymbol - return true if the ast has the given symbol */
1428 /*-----------------------------------------------------------------*/
1430 astHasSymbol (ast * tree, symbol * sym)
1432 if (!tree || IS_AST_LINK (tree))
1435 if (IS_AST_VALUE (tree))
1437 if (IS_AST_SYM_VALUE (tree))
1438 return isSymbolEqual (AST_SYMBOL (tree), sym);
1443 return astHasSymbol (tree->left, sym) ||
1444 astHasSymbol (tree->right, sym);
1447 /*-----------------------------------------------------------------*/
1448 /* astHasDeref - return true if the ast has an indirect access */
1449 /*-----------------------------------------------------------------*/
1451 astHasDeref (ast * tree)
1453 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1456 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1458 return astHasDeref (tree->left) || astHasDeref (tree->right);
1461 /*-----------------------------------------------------------------*/
1462 /* isConformingBody - the loop body has to conform to a set of rules */
1463 /* for the loop to be considered reversible read on for rules */
1464 /*-----------------------------------------------------------------*/
1466 isConformingBody (ast * pbody, symbol * sym, ast * body)
1469 /* we are going to do a pre-order traversal of the
1470 tree && check for the following conditions. (essentially
1471 a set of very shallow tests )
1472 a) the sym passed does not participate in
1473 any arithmetic operation
1474 b) There are no function calls
1475 c) all jumps are within the body
1476 d) address of loop control variable not taken
1477 e) if an assignment has a pointer on the
1478 left hand side make sure right does not have
1479 loop control variable */
1481 /* if we reach the end or a leaf then true */
1482 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1486 /* if anything else is "volatile" */
1487 if (IS_VOLATILE (TETYPE (pbody)))
1490 /* we will walk the body in a pre-order traversal for
1492 switch (pbody->opval.op)
1494 /*------------------------------------------------------------------*/
1496 return isConformingBody (pbody->right, sym, body);
1498 /*------------------------------------------------------------------*/
1503 /*------------------------------------------------------------------*/
1504 case INC_OP: /* incerement operator unary so left only */
1507 /* sure we are not sym is not modified */
1509 IS_AST_SYM_VALUE (pbody->left) &&
1510 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1514 IS_AST_SYM_VALUE (pbody->right) &&
1515 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1520 /*------------------------------------------------------------------*/
1522 case '*': /* can be unary : if right is null then unary operation */
1527 /* if right is NULL then unary operation */
1528 /*------------------------------------------------------------------*/
1529 /*----------------------------*/
1531 /*----------------------------*/
1534 if (IS_AST_SYM_VALUE (pbody->left) &&
1535 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1538 return isConformingBody (pbody->left, sym, body);
1542 if (astHasSymbol (pbody->left, sym) ||
1543 astHasSymbol (pbody->right, sym))
1548 /*------------------------------------------------------------------*/
1556 if (IS_AST_SYM_VALUE (pbody->left) &&
1557 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1560 if (IS_AST_SYM_VALUE (pbody->right) &&
1561 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1564 return isConformingBody (pbody->left, sym, body) &&
1565 isConformingBody (pbody->right, sym, body);
1572 if (IS_AST_SYM_VALUE (pbody->left) &&
1573 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1575 return isConformingBody (pbody->left, sym, body);
1577 /*------------------------------------------------------------------*/
1589 case SIZEOF: /* evaluate wihout code generation */
1591 return isConformingBody (pbody->left, sym, body) &&
1592 isConformingBody (pbody->right, sym, body);
1594 /*------------------------------------------------------------------*/
1597 /* if left has a pointer & right has loop
1598 control variable then we cannot */
1599 if (astHasPointer (pbody->left) &&
1600 astHasSymbol (pbody->right, sym))
1602 if (astHasVolatile (pbody->left))
1605 if (IS_AST_SYM_VALUE (pbody->left) &&
1606 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1609 if (astHasVolatile (pbody->left))
1612 if (astHasDeref(pbody->right)) return FALSE;
1614 return isConformingBody (pbody->left, sym, body) &&
1615 isConformingBody (pbody->right, sym, body);
1626 assert ("Parser should not have generated this\n");
1628 /*------------------------------------------------------------------*/
1629 /*----------------------------*/
1630 /* comma operator */
1631 /*----------------------------*/
1633 return isConformingBody (pbody->left, sym, body) &&
1634 isConformingBody (pbody->right, sym, body);
1636 /*------------------------------------------------------------------*/
1637 /*----------------------------*/
1639 /*----------------------------*/
1643 /*------------------------------------------------------------------*/
1644 /*----------------------------*/
1645 /* return statement */
1646 /*----------------------------*/
1651 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1656 if (astHasSymbol (pbody->left, sym))
1663 return isConformingBody (pbody->left, sym, body) &&
1664 isConformingBody (pbody->right, sym, body);
1670 /*-----------------------------------------------------------------*/
1671 /* isLoopReversible - takes a for loop as input && returns true */
1672 /* if the for loop is reversible. If yes will set the value of */
1673 /* the loop control var & init value & termination value */
1674 /*-----------------------------------------------------------------*/
1676 isLoopReversible (ast * loop, symbol ** loopCntrl,
1677 ast ** init, ast ** end)
1679 /* if option says don't do it then don't */
1680 if (optimize.noLoopReverse)
1682 /* there are several tests to determine this */
1684 /* for loop has to be of the form
1685 for ( <sym> = <const1> ;
1686 [<sym> < <const2>] ;
1687 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1689 if (!isLoopCountable (AST_FOR (loop, initExpr),
1690 AST_FOR (loop, condExpr),
1691 AST_FOR (loop, loopExpr),
1692 loopCntrl, init, end))
1695 /* now do some serious checking on the body of the loop
1698 return isConformingBody (loop->left, *loopCntrl, loop->left);
1702 /*-----------------------------------------------------------------*/
1703 /* replLoopSym - replace the loop sym by loop sym -1 */
1704 /*-----------------------------------------------------------------*/
1706 replLoopSym (ast * body, symbol * sym)
1709 if (!body || IS_AST_LINK (body))
1712 if (IS_AST_SYM_VALUE (body))
1715 if (isSymbolEqual (AST_SYMBOL (body), sym))
1719 body->opval.op = '-';
1720 body->left = newAst_VALUE (symbolVal (sym));
1721 body->right = newAst_VALUE (constVal ("1"));
1729 replLoopSym (body->left, sym);
1730 replLoopSym (body->right, sym);
1734 /*-----------------------------------------------------------------*/
1735 /* reverseLoop - do the actual loop reversal */
1736 /*-----------------------------------------------------------------*/
1738 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1742 /* create the following tree
1747 if (sym) goto for_continue ;
1750 /* put it together piece by piece */
1751 rloop = newNode (NULLOP,
1752 createIf (newAst_VALUE (symbolVal (sym)),
1754 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1757 newAst_VALUE (symbolVal (sym)),
1760 replLoopSym (loop->left, sym);
1762 rloop = newNode (NULLOP,
1764 newAst_VALUE (symbolVal (sym)),
1765 newNode ('-', end, init)),
1766 createLabel (AST_FOR (loop, continueLabel),
1770 newNode (SUB_ASSIGN,
1771 newAst_VALUE (symbolVal (sym)),
1772 newAst_VALUE (constVal ("1"))),
1775 return decorateType (rloop);
1779 /*-----------------------------------------------------------------*/
1780 /* decorateType - compute type for this tree also does type cheking */
1781 /* this is done bottom up, since type have to flow upwards */
1782 /* it also does constant folding, and paramater checking */
1783 /*-----------------------------------------------------------------*/
1785 decorateType (ast * tree)
1793 /* if already has type then do nothing */
1794 if (tree->decorated)
1797 tree->decorated = 1;
1799 /* print the line */
1800 /* if not block & function */
1801 if (tree->type == EX_OP &&
1802 (tree->opval.op != FUNCTION &&
1803 tree->opval.op != BLOCK &&
1804 tree->opval.op != NULLOP))
1806 filename = tree->filename;
1807 lineno = tree->lineno;
1810 /* if any child is an error | this one is an error do nothing */
1811 if (tree->isError ||
1812 (tree->left && tree->left->isError) ||
1813 (tree->right && tree->right->isError))
1816 /*------------------------------------------------------------------*/
1817 /*----------------------------*/
1818 /* leaf has been reached */
1819 /*----------------------------*/
1820 /* if this is of type value */
1821 /* just get the type */
1822 if (tree->type == EX_VALUE)
1825 if (IS_LITERAL (tree->opval.val->etype))
1828 /* if this is a character array then declare it */
1829 if (IS_ARRAY (tree->opval.val->type))
1830 tree->opval.val = stringToSymbol (tree->opval.val);
1832 /* otherwise just copy the type information */
1833 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1837 if (tree->opval.val->sym)
1839 /* if the undefined flag is set then give error message */
1840 if (tree->opval.val->sym->undefined)
1842 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1844 TTYPE (tree) = TETYPE (tree) =
1845 tree->opval.val->type = tree->opval.val->sym->type =
1846 tree->opval.val->etype = tree->opval.val->sym->etype =
1847 copyLinkChain (INTTYPE);
1852 /* if impilicit i.e. struct/union member then no type */
1853 if (tree->opval.val->sym->implicit)
1854 TTYPE (tree) = TETYPE (tree) = NULL;
1859 /* else copy the type */
1860 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1862 /* and mark it as referenced */
1863 tree->opval.val->sym->isref = 1;
1871 /* if type link for the case of cast */
1872 if (tree->type == EX_LINK)
1874 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1881 dtl = decorateType (tree->left);
1882 /* delay right side for '?' operator since conditional macro expansions might
1884 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1886 /* this is to take care of situations
1887 when the tree gets rewritten */
1888 if (dtl != tree->left)
1890 if (dtr != tree->right)
1894 /* depending on type of operator do */
1896 switch (tree->opval.op)
1898 /*------------------------------------------------------------------*/
1899 /*----------------------------*/
1901 /*----------------------------*/
1904 /* determine which is the array & which the index */
1905 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1908 ast *tempTree = tree->left;
1909 tree->left = tree->right;
1910 tree->right = tempTree;
1913 /* first check if this is a array or a pointer */
1914 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1916 werror (E_NEED_ARRAY_PTR, "[]");
1917 goto errorTreeReturn;
1920 /* check if the type of the idx */
1921 if (!IS_INTEGRAL (RTYPE (tree)))
1923 werror (E_IDX_NOT_INT);
1924 goto errorTreeReturn;
1927 /* if the left is an rvalue then error */
1930 werror (E_LVALUE_REQUIRED, "array access");
1931 goto errorTreeReturn;
1934 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1935 if (IS_PTR(LTYPE(tree))) {
1936 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1940 /*------------------------------------------------------------------*/
1941 /*----------------------------*/
1943 /*----------------------------*/
1945 /* if this is not a structure */
1946 if (!IS_STRUCT (LTYPE (tree)))
1948 werror (E_STRUCT_UNION, ".");
1949 goto errorTreeReturn;
1951 TTYPE (tree) = structElemType (LTYPE (tree),
1952 (tree->right->type == EX_VALUE ?
1953 tree->right->opval.val : NULL));
1954 TETYPE (tree) = getSpec (TTYPE (tree));
1957 /*------------------------------------------------------------------*/
1958 /*----------------------------*/
1959 /* struct/union pointer */
1960 /*----------------------------*/
1962 /* if not pointer to a structure */
1963 if (!IS_PTR (LTYPE (tree)))
1965 werror (E_PTR_REQD);
1966 goto errorTreeReturn;
1969 if (!IS_STRUCT (LTYPE (tree)->next))
1971 werror (E_STRUCT_UNION, "->");
1972 goto errorTreeReturn;
1975 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1976 (tree->right->type == EX_VALUE ?
1977 tree->right->opval.val : NULL));
1978 TETYPE (tree) = getSpec (TTYPE (tree));
1980 /* adjust the storage class */
1981 switch (DCL_TYPE(tree->left->ftype)) {
1985 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
1988 SPEC_SCLS(TETYPE(tree)) = S_CODE;
1993 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
1996 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
1999 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2008 /*------------------------------------------------------------------*/
2009 /*----------------------------*/
2010 /* ++/-- operation */
2011 /*----------------------------*/
2012 case INC_OP: /* incerement operator unary so left only */
2015 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2016 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2017 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2018 werror (E_CODE_WRITE, "++/--");
2027 /*------------------------------------------------------------------*/
2028 /*----------------------------*/
2030 /*----------------------------*/
2031 case '&': /* can be unary */
2032 /* if right is NULL then unary operation */
2033 if (tree->right) /* not an unary operation */
2036 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2038 werror (E_BITWISE_OP);
2039 werror (W_CONTINUE, "left & right types are ");
2040 printTypeChain (LTYPE (tree), stderr);
2041 fprintf (stderr, ",");
2042 printTypeChain (RTYPE (tree), stderr);
2043 fprintf (stderr, "\n");
2044 goto errorTreeReturn;
2047 /* if they are both literal */
2048 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2050 tree->type = EX_VALUE;
2051 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2052 valFromType (RETYPE (tree)), '&');
2054 tree->right = tree->left = NULL;
2055 TETYPE (tree) = tree->opval.val->etype;
2056 TTYPE (tree) = tree->opval.val->type;
2060 /* see if this is a GETHBIT operation if yes
2063 ast *otree = optimizeGetHbit (tree);
2066 return decorateType (otree);
2070 computeType (LTYPE (tree), RTYPE (tree));
2071 TETYPE (tree) = getSpec (TTYPE (tree));
2073 LRVAL (tree) = RRVAL (tree) = 1;
2077 /*------------------------------------------------------------------*/
2078 /*----------------------------*/
2080 /*----------------------------*/
2082 p->class = DECLARATOR;
2083 /* if bit field then error */
2084 if (IS_BITVAR (tree->left->etype))
2086 werror (E_ILLEGAL_ADDR, "address of bit variable");
2087 goto errorTreeReturn;
2090 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2092 werror (E_ILLEGAL_ADDR, "address of register variable");
2093 goto errorTreeReturn;
2096 if (IS_FUNC (LTYPE (tree)))
2098 werror (E_ILLEGAL_ADDR, "address of function");
2099 goto errorTreeReturn;
2102 if (IS_LITERAL(LTYPE(tree)))
2104 werror (E_ILLEGAL_ADDR, "address of literal");
2105 goto errorTreeReturn;
2110 werror (E_LVALUE_REQUIRED, "address of");
2111 goto errorTreeReturn;
2113 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2115 DCL_TYPE (p) = CPOINTER;
2116 DCL_PTR_CONST (p) = port->mem.code_ro;
2118 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2119 DCL_TYPE (p) = FPOINTER;
2120 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2121 DCL_TYPE (p) = PPOINTER;
2122 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2123 DCL_TYPE (p) = IPOINTER;
2124 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2125 DCL_TYPE (p) = EEPPOINTER;
2126 else if (SPEC_OCLS(tree->left->etype))
2127 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2129 DCL_TYPE (p) = POINTER;
2131 if (IS_AST_SYM_VALUE (tree->left))
2133 AST_SYMBOL (tree->left)->addrtaken = 1;
2134 AST_SYMBOL (tree->left)->allocreq = 1;
2137 p->next = LTYPE (tree);
2139 TETYPE (tree) = getSpec (TTYPE (tree));
2140 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2141 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2146 /*------------------------------------------------------------------*/
2147 /*----------------------------*/
2149 /*----------------------------*/
2151 /* if the rewrite succeeds then don't go any furthur */
2153 ast *wtree = optimizeRRCRLC (tree);
2155 return decorateType (wtree);
2157 /*------------------------------------------------------------------*/
2158 /*----------------------------*/
2160 /*----------------------------*/
2162 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2164 werror (E_BITWISE_OP);
2165 werror (W_CONTINUE, "left & right types are ");
2166 printTypeChain (LTYPE (tree), stderr);
2167 fprintf (stderr, ",");
2168 printTypeChain (RTYPE (tree), stderr);
2169 fprintf (stderr, "\n");
2170 goto errorTreeReturn;
2173 /* if they are both literal then */
2174 /* rewrite the tree */
2175 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2177 tree->type = EX_VALUE;
2178 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2179 valFromType (RETYPE (tree)),
2181 tree->right = tree->left = NULL;
2182 TETYPE (tree) = tree->opval.val->etype;
2183 TTYPE (tree) = tree->opval.val->type;
2186 LRVAL (tree) = RRVAL (tree) = 1;
2187 TETYPE (tree) = getSpec (TTYPE (tree) =
2188 computeType (LTYPE (tree),
2191 /*------------------------------------------------------------------*/
2192 /*----------------------------*/
2194 /*----------------------------*/
2196 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2198 werror (E_INVALID_OP, "divide");
2199 goto errorTreeReturn;
2201 /* if they are both literal then */
2202 /* rewrite the tree */
2203 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2205 tree->type = EX_VALUE;
2206 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2207 valFromType (RETYPE (tree)));
2208 tree->right = tree->left = NULL;
2209 TETYPE (tree) = getSpec (TTYPE (tree) =
2210 tree->opval.val->type);
2213 LRVAL (tree) = RRVAL (tree) = 1;
2214 TETYPE (tree) = getSpec (TTYPE (tree) =
2215 computeType (LTYPE (tree),
2219 /*------------------------------------------------------------------*/
2220 /*----------------------------*/
2222 /*----------------------------*/
2224 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2226 werror (E_BITWISE_OP);
2227 werror (W_CONTINUE, "left & right types are ");
2228 printTypeChain (LTYPE (tree), stderr);
2229 fprintf (stderr, ",");
2230 printTypeChain (RTYPE (tree), stderr);
2231 fprintf (stderr, "\n");
2232 goto errorTreeReturn;
2234 /* if they are both literal then */
2235 /* rewrite the tree */
2236 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2238 tree->type = EX_VALUE;
2239 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2240 valFromType (RETYPE (tree)));
2241 tree->right = tree->left = NULL;
2242 TETYPE (tree) = getSpec (TTYPE (tree) =
2243 tree->opval.val->type);
2246 LRVAL (tree) = RRVAL (tree) = 1;
2247 TETYPE (tree) = getSpec (TTYPE (tree) =
2248 computeType (LTYPE (tree),
2252 /*------------------------------------------------------------------*/
2253 /*----------------------------*/
2254 /* address dereference */
2255 /*----------------------------*/
2256 case '*': /* can be unary : if right is null then unary operation */
2259 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2261 werror (E_PTR_REQD);
2262 goto errorTreeReturn;
2267 werror (E_LVALUE_REQUIRED, "pointer deref");
2268 goto errorTreeReturn;
2270 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2271 LTYPE (tree)->next : NULL);
2272 TETYPE (tree) = getSpec (TTYPE (tree));
2273 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2277 /*------------------------------------------------------------------*/
2278 /*----------------------------*/
2279 /* multiplication */
2280 /*----------------------------*/
2281 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2283 werror (E_INVALID_OP, "multiplication");
2284 goto errorTreeReturn;
2287 /* if they are both literal then */
2288 /* rewrite the tree */
2289 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2291 tree->type = EX_VALUE;
2292 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2293 valFromType (RETYPE (tree)));
2294 tree->right = tree->left = NULL;
2295 TETYPE (tree) = getSpec (TTYPE (tree) =
2296 tree->opval.val->type);
2300 /* if left is a literal exchange left & right */
2301 if (IS_LITERAL (LTYPE (tree)))
2303 ast *tTree = tree->left;
2304 tree->left = tree->right;
2305 tree->right = tTree;
2308 LRVAL (tree) = RRVAL (tree) = 1;
2309 /* promote result to int if left & right are char
2310 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2311 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2312 TETYPE (tree) = getSpec (TTYPE (tree) =
2313 computeType (LTYPE (tree),
2315 SPEC_NOUN(TETYPE(tree)) = V_INT;
2317 TETYPE (tree) = getSpec (TTYPE (tree) =
2318 computeType (LTYPE (tree),
2323 /*------------------------------------------------------------------*/
2324 /*----------------------------*/
2325 /* unary '+' operator */
2326 /*----------------------------*/
2331 if (!IS_INTEGRAL (LTYPE (tree)))
2333 werror (E_UNARY_OP, '+');
2334 goto errorTreeReturn;
2337 /* if left is a literal then do it */
2338 if (IS_LITERAL (LTYPE (tree)))
2340 tree->type = EX_VALUE;
2341 tree->opval.val = valFromType (LETYPE (tree));
2343 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2347 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2351 /*------------------------------------------------------------------*/
2352 /*----------------------------*/
2354 /*----------------------------*/
2356 /* this is not a unary operation */
2357 /* if both pointers then problem */
2358 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2359 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2361 werror (E_PTR_PLUS_PTR);
2362 goto errorTreeReturn;
2365 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2366 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2368 werror (E_PLUS_INVALID, "+");
2369 goto errorTreeReturn;
2372 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2373 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2375 werror (E_PLUS_INVALID, "+");
2376 goto errorTreeReturn;
2378 /* if they are both literal then */
2379 /* rewrite the tree */
2380 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2382 tree->type = EX_VALUE;
2383 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2384 valFromType (RETYPE (tree)));
2385 tree->right = tree->left = NULL;
2386 TETYPE (tree) = getSpec (TTYPE (tree) =
2387 tree->opval.val->type);
2391 /* if the right is a pointer or left is a literal
2392 xchange left & right */
2393 if (IS_ARRAY (RTYPE (tree)) ||
2394 IS_PTR (RTYPE (tree)) ||
2395 IS_LITERAL (LTYPE (tree)))
2397 ast *tTree = tree->left;
2398 tree->left = tree->right;
2399 tree->right = tTree;
2402 LRVAL (tree) = RRVAL (tree) = 1;
2403 /* if the left is a pointer */
2404 if (IS_PTR (LTYPE (tree)))
2405 TETYPE (tree) = getSpec (TTYPE (tree) =
2408 TETYPE (tree) = getSpec (TTYPE (tree) =
2409 computeType (LTYPE (tree),
2413 /*------------------------------------------------------------------*/
2414 /*----------------------------*/
2416 /*----------------------------*/
2417 case '-': /* can be unary */
2418 /* if right is null then unary */
2422 if (!IS_ARITHMETIC (LTYPE (tree)))
2424 werror (E_UNARY_OP, tree->opval.op);
2425 goto errorTreeReturn;
2428 /* if left is a literal then do it */
2429 if (IS_LITERAL (LTYPE (tree)))
2431 tree->type = EX_VALUE;
2432 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2434 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2435 SPEC_USIGN(TETYPE(tree)) = 0;
2439 TTYPE (tree) = LTYPE (tree);
2443 /*------------------------------------------------------------------*/
2444 /*----------------------------*/
2446 /*----------------------------*/
2448 if (!(IS_PTR (LTYPE (tree)) ||
2449 IS_ARRAY (LTYPE (tree)) ||
2450 IS_ARITHMETIC (LTYPE (tree))))
2452 werror (E_PLUS_INVALID, "-");
2453 goto errorTreeReturn;
2456 if (!(IS_PTR (RTYPE (tree)) ||
2457 IS_ARRAY (RTYPE (tree)) ||
2458 IS_ARITHMETIC (RTYPE (tree))))
2460 werror (E_PLUS_INVALID, "-");
2461 goto errorTreeReturn;
2464 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2465 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2466 IS_INTEGRAL (RTYPE (tree))))
2468 werror (E_PLUS_INVALID, "-");
2469 goto errorTreeReturn;
2472 /* if they are both literal then */
2473 /* rewrite the tree */
2474 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2476 tree->type = EX_VALUE;
2477 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2478 valFromType (RETYPE (tree)));
2479 tree->right = tree->left = NULL;
2480 TETYPE (tree) = getSpec (TTYPE (tree) =
2481 tree->opval.val->type);
2485 /* if the left & right are equal then zero */
2486 if (isAstEqual (tree->left, tree->right))
2488 tree->type = EX_VALUE;
2489 tree->left = tree->right = NULL;
2490 tree->opval.val = constVal ("0");
2491 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2495 /* if both of them are pointers or arrays then */
2496 /* the result is going to be an integer */
2497 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2498 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2499 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2501 /* if only the left is a pointer */
2502 /* then result is a pointer */
2503 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2504 TETYPE (tree) = getSpec (TTYPE (tree) =
2507 TETYPE (tree) = getSpec (TTYPE (tree) =
2508 computeType (LTYPE (tree),
2510 LRVAL (tree) = RRVAL (tree) = 1;
2513 /*------------------------------------------------------------------*/
2514 /*----------------------------*/
2516 /*----------------------------*/
2518 /* can be only integral type */
2519 if (!IS_INTEGRAL (LTYPE (tree)))
2521 werror (E_UNARY_OP, tree->opval.op);
2522 goto errorTreeReturn;
2525 /* if left is a literal then do it */
2526 if (IS_LITERAL (LTYPE (tree)))
2528 tree->type = EX_VALUE;
2529 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2531 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2535 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2538 /*------------------------------------------------------------------*/
2539 /*----------------------------*/
2541 /*----------------------------*/
2543 /* can be pointer */
2544 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2545 !IS_PTR (LTYPE (tree)) &&
2546 !IS_ARRAY (LTYPE (tree)))
2548 werror (E_UNARY_OP, tree->opval.op);
2549 goto errorTreeReturn;
2552 /* if left is a literal then do it */
2553 if (IS_LITERAL (LTYPE (tree)))
2555 tree->type = EX_VALUE;
2556 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2558 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2562 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2565 /*------------------------------------------------------------------*/
2566 /*----------------------------*/
2568 /*----------------------------*/
2571 TTYPE (tree) = LTYPE (tree);
2572 TETYPE (tree) = LETYPE (tree);
2576 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2581 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2583 werror (E_SHIFT_OP_INVALID);
2584 werror (W_CONTINUE, "left & right types are ");
2585 printTypeChain (LTYPE (tree), stderr);
2586 fprintf (stderr, ",");
2587 printTypeChain (RTYPE (tree), stderr);
2588 fprintf (stderr, "\n");
2589 goto errorTreeReturn;
2592 /* if they are both literal then */
2593 /* rewrite the tree */
2594 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2596 tree->type = EX_VALUE;
2597 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2598 valFromType (RETYPE (tree)),
2599 (tree->opval.op == LEFT_OP ? 1 : 0));
2600 tree->right = tree->left = NULL;
2601 TETYPE (tree) = getSpec (TTYPE (tree) =
2602 tree->opval.val->type);
2605 /* if only the right side is a literal & we are
2606 shifting more than size of the left operand then zero */
2607 if (IS_LITERAL (RTYPE (tree)) &&
2608 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2609 (getSize (LTYPE (tree)) * 8))
2611 werror (W_SHIFT_CHANGED,
2612 (tree->opval.op == LEFT_OP ? "left" : "right"));
2613 tree->type = EX_VALUE;
2614 tree->left = tree->right = NULL;
2615 tree->opval.val = constVal ("0");
2616 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2619 LRVAL (tree) = RRVAL (tree) = 1;
2620 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2622 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2626 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2630 /*------------------------------------------------------------------*/
2631 /*----------------------------*/
2633 /*----------------------------*/
2634 case CAST: /* change the type */
2635 /* cannot cast to an aggregate type */
2636 if (IS_AGGREGATE (LTYPE (tree)))
2638 werror (E_CAST_ILLEGAL);
2639 goto errorTreeReturn;
2642 /* make sure the type is complete and sane */
2643 checkTypeSanity(LETYPE(tree), "(cast)");
2646 /* if the right is a literal replace the tree */
2647 if (IS_LITERAL (RETYPE (tree))) {
2648 if (!IS_PTR (LTYPE (tree))) {
2649 tree->type = EX_VALUE;
2651 valCastLiteral (LTYPE (tree),
2652 floatFromVal (valFromType (RETYPE (tree))));
2655 TTYPE (tree) = tree->opval.val->type;
2656 tree->values.literalFromCast = 1;
2657 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2658 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2659 sym_link *rest = LTYPE(tree)->next;
2660 werror(W_LITERAL_GENERIC);
2661 TTYPE(tree) = newLink();
2662 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2663 TTYPE(tree)->next = rest;
2664 tree->left->opval.lnk = TTYPE(tree);
2667 TTYPE (tree) = LTYPE (tree);
2671 TTYPE (tree) = LTYPE (tree);
2675 /* if pointer to struct then check names */
2676 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2677 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2678 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2679 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2681 /* if the right is a literal replace the tree */
2682 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2683 tree->type = EX_VALUE;
2685 valCastLiteral (LTYPE (tree),
2686 floatFromVal (valFromType (RETYPE (tree))));
2689 TTYPE (tree) = tree->opval.val->type;
2690 tree->values.literalFromCast = 1;
2692 TTYPE (tree) = LTYPE (tree);
2696 TETYPE (tree) = getSpec (TTYPE (tree));
2700 /*------------------------------------------------------------------*/
2701 /*----------------------------*/
2702 /* logical &&, || */
2703 /*----------------------------*/
2706 /* each must me arithmetic type or be a pointer */
2707 if (!IS_PTR (LTYPE (tree)) &&
2708 !IS_ARRAY (LTYPE (tree)) &&
2709 !IS_INTEGRAL (LTYPE (tree)))
2711 werror (E_COMPARE_OP);
2712 goto errorTreeReturn;
2715 if (!IS_PTR (RTYPE (tree)) &&
2716 !IS_ARRAY (RTYPE (tree)) &&
2717 !IS_INTEGRAL (RTYPE (tree)))
2719 werror (E_COMPARE_OP);
2720 goto errorTreeReturn;
2722 /* if they are both literal then */
2723 /* rewrite the tree */
2724 if (IS_LITERAL (RTYPE (tree)) &&
2725 IS_LITERAL (LTYPE (tree)))
2727 tree->type = EX_VALUE;
2728 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2729 valFromType (RETYPE (tree)),
2731 tree->right = tree->left = NULL;
2732 TETYPE (tree) = getSpec (TTYPE (tree) =
2733 tree->opval.val->type);
2736 LRVAL (tree) = RRVAL (tree) = 1;
2737 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2740 /*------------------------------------------------------------------*/
2741 /*----------------------------*/
2742 /* comparison operators */
2743 /*----------------------------*/
2751 ast *lt = optimizeCompare (tree);
2757 /* if they are pointers they must be castable */
2758 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2760 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2762 werror (E_COMPARE_OP);
2763 fprintf (stderr, "comparing type ");
2764 printTypeChain (LTYPE (tree), stderr);
2765 fprintf (stderr, "to type ");
2766 printTypeChain (RTYPE (tree), stderr);
2767 fprintf (stderr, "\n");
2768 goto errorTreeReturn;
2771 /* else they should be promotable to one another */
2774 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2775 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2777 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2779 werror (E_COMPARE_OP);
2780 fprintf (stderr, "comparing type ");
2781 printTypeChain (LTYPE (tree), stderr);
2782 fprintf (stderr, "to type ");
2783 printTypeChain (RTYPE (tree), stderr);
2784 fprintf (stderr, "\n");
2785 goto errorTreeReturn;
2788 /* if unsigned value < 0 then always false */
2789 /* if (unsigned value) > 0 then (unsigned value) */
2790 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2791 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2793 if (tree->opval.op == '<') {
2796 if (tree->opval.op == '>') {
2800 /* if they are both literal then */
2801 /* rewrite the tree */
2802 if (IS_LITERAL (RTYPE (tree)) &&
2803 IS_LITERAL (LTYPE (tree)))
2805 tree->type = EX_VALUE;
2806 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2807 valFromType (RETYPE (tree)),
2809 tree->right = tree->left = NULL;
2810 TETYPE (tree) = getSpec (TTYPE (tree) =
2811 tree->opval.val->type);
2814 LRVAL (tree) = RRVAL (tree) = 1;
2815 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2818 /*------------------------------------------------------------------*/
2819 /*----------------------------*/
2821 /*----------------------------*/
2822 case SIZEOF: /* evaluate wihout code generation */
2823 /* change the type to a integer */
2824 tree->type = EX_VALUE;
2825 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2826 tree->opval.val = constVal (buffer);
2827 tree->right = tree->left = NULL;
2828 TETYPE (tree) = getSpec (TTYPE (tree) =
2829 tree->opval.val->type);
2832 /*------------------------------------------------------------------*/
2833 /*----------------------------*/
2835 /*----------------------------*/
2837 /* return typeof enum value */
2838 tree->type = EX_VALUE;
2841 if (IS_SPEC(tree->right->ftype)) {
2842 switch (SPEC_NOUN(tree->right->ftype)) {
2844 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2845 else typeofv = TYPEOF_INT;
2848 typeofv = TYPEOF_FLOAT;
2851 typeofv = TYPEOF_CHAR;
2854 typeofv = TYPEOF_VOID;
2857 typeofv = TYPEOF_STRUCT;
2860 typeofv = TYPEOF_BIT;
2863 typeofv = TYPEOF_SBIT;
2869 switch (DCL_TYPE(tree->right->ftype)) {
2871 typeofv = TYPEOF_POINTER;
2874 typeofv = TYPEOF_FPOINTER;
2877 typeofv = TYPEOF_CPOINTER;
2880 typeofv = TYPEOF_GPOINTER;
2883 typeofv = TYPEOF_PPOINTER;
2886 typeofv = TYPEOF_IPOINTER;
2889 typeofv = TYPEOF_ARRAY;
2892 typeofv = TYPEOF_FUNCTION;
2898 sprintf (buffer, "%d", typeofv);
2899 tree->opval.val = constVal (buffer);
2900 tree->right = tree->left = NULL;
2901 TETYPE (tree) = getSpec (TTYPE (tree) =
2902 tree->opval.val->type);
2905 /*------------------------------------------------------------------*/
2906 /*----------------------------*/
2907 /* conditional operator '?' */
2908 /*----------------------------*/
2910 /* the type is value of the colon operator (on the right) */
2911 assert(IS_COLON_OP(tree->right));
2912 /* if already known then replace the tree : optimizer will do it
2913 but faster to do it here */
2914 if (IS_LITERAL (LTYPE(tree))) {
2915 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2916 return decorateType(tree->right->left) ;
2918 return decorateType(tree->right->right) ;
2921 tree->right = decorateType(tree->right);
2922 TTYPE (tree) = RTYPE(tree);
2923 TETYPE (tree) = getSpec (TTYPE (tree));
2928 /* if they don't match we have a problem */
2929 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2931 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2932 goto errorTreeReturn;
2935 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2936 TETYPE (tree) = getSpec (TTYPE (tree));
2940 /*------------------------------------------------------------------*/
2941 /*----------------------------*/
2942 /* assignment operators */
2943 /*----------------------------*/
2946 /* for these it must be both must be integral */
2947 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2948 !IS_ARITHMETIC (RTYPE (tree)))
2950 werror (E_OPS_INTEGRAL);
2951 goto errorTreeReturn;
2954 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2956 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2957 werror (E_CODE_WRITE, " ");
2961 werror (E_LVALUE_REQUIRED, "*= or /=");
2962 goto errorTreeReturn;
2973 /* for these it must be both must be integral */
2974 if (!IS_INTEGRAL (LTYPE (tree)) ||
2975 !IS_INTEGRAL (RTYPE (tree)))
2977 werror (E_OPS_INTEGRAL);
2978 goto errorTreeReturn;
2981 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2983 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2984 werror (E_CODE_WRITE, " ");
2988 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2989 goto errorTreeReturn;
2995 /*------------------------------------------------------------------*/
2996 /*----------------------------*/
2998 /*----------------------------*/
3000 if (!(IS_PTR (LTYPE (tree)) ||
3001 IS_ARITHMETIC (LTYPE (tree))))
3003 werror (E_PLUS_INVALID, "-=");
3004 goto errorTreeReturn;
3007 if (!(IS_PTR (RTYPE (tree)) ||
3008 IS_ARITHMETIC (RTYPE (tree))))
3010 werror (E_PLUS_INVALID, "-=");
3011 goto errorTreeReturn;
3014 TETYPE (tree) = getSpec (TTYPE (tree) =
3015 computeType (LTYPE (tree),
3018 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3019 werror (E_CODE_WRITE, " ");
3023 werror (E_LVALUE_REQUIRED, "-=");
3024 goto errorTreeReturn;
3030 /*------------------------------------------------------------------*/
3031 /*----------------------------*/
3033 /*----------------------------*/
3035 /* this is not a unary operation */
3036 /* if both pointers then problem */
3037 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3039 werror (E_PTR_PLUS_PTR);
3040 goto errorTreeReturn;
3043 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3045 werror (E_PLUS_INVALID, "+=");
3046 goto errorTreeReturn;
3049 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3051 werror (E_PLUS_INVALID, "+=");
3052 goto errorTreeReturn;
3055 TETYPE (tree) = getSpec (TTYPE (tree) =
3056 computeType (LTYPE (tree),
3059 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3060 werror (E_CODE_WRITE, " ");
3064 werror (E_LVALUE_REQUIRED, "+=");
3065 goto errorTreeReturn;
3068 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3069 tree->opval.op = '=';
3073 /*------------------------------------------------------------------*/
3074 /*----------------------------*/
3075 /* straight assignemnt */
3076 /*----------------------------*/
3078 /* cannot be an aggregate */
3079 if (IS_AGGREGATE (LTYPE (tree)))
3081 werror (E_AGGR_ASSIGN);
3082 goto errorTreeReturn;
3085 /* they should either match or be castable */
3086 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3088 werror (E_TYPE_MISMATCH, "assignment", " ");
3089 fprintf (stderr, "type --> '");
3090 printTypeChain (RTYPE (tree), stderr);
3091 fprintf (stderr, "' ");
3092 fprintf (stderr, "assigned to type --> '");
3093 printTypeChain (LTYPE (tree), stderr);
3094 fprintf (stderr, "'\n");
3095 goto errorTreeReturn;
3098 /* if the left side of the tree is of type void
3099 then report error */
3100 if (IS_VOID (LTYPE (tree)))
3102 werror (E_CAST_ZERO);
3103 printFromToType(RTYPE(tree), LTYPE(tree));
3106 TETYPE (tree) = getSpec (TTYPE (tree) =
3110 if (!tree->initMode ) {
3111 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3112 werror (E_CODE_WRITE, " ");
3116 werror (E_LVALUE_REQUIRED, "=");
3117 goto errorTreeReturn;
3122 /*------------------------------------------------------------------*/
3123 /*----------------------------*/
3124 /* comma operator */
3125 /*----------------------------*/
3127 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3130 /*------------------------------------------------------------------*/
3131 /*----------------------------*/
3133 /*----------------------------*/
3137 if (processParms (tree->left,
3138 FUNC_ARGS(tree->left->ftype),
3139 tree->right, &parmNumber, TRUE)) {
3140 goto errorTreeReturn;
3143 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3144 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3146 //FUNC_ARGS(tree->left->ftype) =
3147 //reverseVal (FUNC_ARGS(tree->left->ftype));
3148 reverseParms (tree->right);
3151 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3154 /*------------------------------------------------------------------*/
3155 /*----------------------------*/
3156 /* return statement */
3157 /*----------------------------*/
3162 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3164 werror (W_RETURN_MISMATCH);
3165 printFromToType (RTYPE(tree), currFunc->type->next);
3166 goto errorTreeReturn;
3169 if (IS_VOID (currFunc->type->next)
3171 !IS_VOID (RTYPE (tree)))
3173 werror (E_FUNC_VOID);
3174 goto errorTreeReturn;
3177 /* if there is going to be a casing required then add it */
3178 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3181 decorateType (newNode (CAST,
3182 newAst_LINK (copyLinkChain (currFunc->type->next)),
3191 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3193 werror (E_VOID_FUNC, currFunc->name);
3194 goto errorTreeReturn;
3197 TTYPE (tree) = TETYPE (tree) = NULL;
3200 /*------------------------------------------------------------------*/
3201 /*----------------------------*/
3202 /* switch statement */
3203 /*----------------------------*/
3205 /* the switch value must be an integer */
3206 if (!IS_INTEGRAL (LTYPE (tree)))
3208 werror (E_SWITCH_NON_INTEGER);
3209 goto errorTreeReturn;
3212 TTYPE (tree) = TETYPE (tree) = NULL;
3215 /*------------------------------------------------------------------*/
3216 /*----------------------------*/
3218 /*----------------------------*/
3220 tree->left = backPatchLabels (tree->left,
3223 TTYPE (tree) = TETYPE (tree) = NULL;
3226 /*------------------------------------------------------------------*/
3227 /*----------------------------*/
3229 /*----------------------------*/
3232 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3233 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3234 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3236 /* if the for loop is reversible then
3237 reverse it otherwise do what we normally
3243 if (isLoopReversible (tree, &sym, &init, &end))
3244 return reverseLoop (tree, sym, init, end);
3246 return decorateType (createFor (AST_FOR (tree, trueLabel),
3247 AST_FOR (tree, continueLabel),
3248 AST_FOR (tree, falseLabel),
3249 AST_FOR (tree, condLabel),
3250 AST_FOR (tree, initExpr),
3251 AST_FOR (tree, condExpr),
3252 AST_FOR (tree, loopExpr),
3256 TTYPE (tree) = TETYPE (tree) = NULL;
3260 /* some error found this tree will be killed */
3262 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3263 tree->opval.op = NULLOP;
3269 /*-----------------------------------------------------------------*/
3270 /* sizeofOp - processes size of operation */
3271 /*-----------------------------------------------------------------*/
3273 sizeofOp (sym_link * type)
3277 /* make sure the type is complete and sane */
3278 checkTypeSanity(type, "(sizeof)");
3280 /* get the size and convert it to character */
3281 sprintf (buff, "%d", getSize (type));
3283 /* now convert into value */
3284 return constVal (buff);
3288 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3289 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3290 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3291 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3292 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3293 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3294 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3296 /*-----------------------------------------------------------------*/
3297 /* backPatchLabels - change and or not operators to flow control */
3298 /*-----------------------------------------------------------------*/
3300 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3306 if (!(IS_ANDORNOT (tree)))
3309 /* if this an and */
3312 static int localLbl = 0;
3315 sprintf (buffer, "_and_%d", localLbl++);
3316 localLabel = newSymbol (buffer, NestLevel);
3318 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3320 /* if left is already a IFX then just change the if true label in that */
3321 if (!IS_IFX (tree->left))
3322 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3324 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3325 /* right is a IFX then just join */
3326 if (IS_IFX (tree->right))
3327 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3329 tree->right = createLabel (localLabel, tree->right);
3330 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3332 return newNode (NULLOP, tree->left, tree->right);
3335 /* if this is an or operation */
3338 static int localLbl = 0;
3341 sprintf (buffer, "_or_%d", localLbl++);
3342 localLabel = newSymbol (buffer, NestLevel);
3344 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3346 /* if left is already a IFX then just change the if true label in that */
3347 if (!IS_IFX (tree->left))
3348 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3350 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3351 /* right is a IFX then just join */
3352 if (IS_IFX (tree->right))
3353 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3355 tree->right = createLabel (localLabel, tree->right);
3356 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3358 return newNode (NULLOP, tree->left, tree->right);
3364 int wasnot = IS_NOT (tree->left);
3365 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3367 /* if the left is already a IFX */
3368 if (!IS_IFX (tree->left))
3369 tree->left = newNode (IFX, tree->left, NULL);
3373 tree->left->trueLabel = trueLabel;
3374 tree->left->falseLabel = falseLabel;
3378 tree->left->trueLabel = falseLabel;
3379 tree->left->falseLabel = trueLabel;
3386 tree->trueLabel = trueLabel;
3387 tree->falseLabel = falseLabel;
3394 /*-----------------------------------------------------------------*/
3395 /* createBlock - create expression tree for block */
3396 /*-----------------------------------------------------------------*/
3398 createBlock (symbol * decl, ast * body)
3402 /* if the block has nothing */
3406 ex = newNode (BLOCK, NULL, body);
3407 ex->values.sym = decl;
3409 ex->right = ex->right;
3415 /*-----------------------------------------------------------------*/
3416 /* createLabel - creates the expression tree for labels */
3417 /*-----------------------------------------------------------------*/
3419 createLabel (symbol * label, ast * stmnt)
3422 char name[SDCC_NAME_MAX + 1];
3425 /* must create fresh symbol if the symbol name */
3426 /* exists in the symbol table, since there can */
3427 /* be a variable with the same name as the labl */
3428 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3429 (csym->level == label->level))
3430 label = newSymbol (label->name, label->level);
3432 /* change the name before putting it in add _ */
3433 sprintf (name, "%s", label->name);
3435 /* put the label in the LabelSymbol table */
3436 /* but first check if a label of the same */
3438 if ((csym = findSym (LabelTab, NULL, name)))
3439 werror (E_DUPLICATE_LABEL, label->name);
3441 addSym (LabelTab, label, name, label->level, 0, 0);
3444 label->key = labelKey++;
3445 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3451 /*-----------------------------------------------------------------*/
3452 /* createCase - generates the parsetree for a case statement */
3453 /*-----------------------------------------------------------------*/
3455 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3457 char caseLbl[SDCC_NAME_MAX + 1];
3461 /* if the switch statement does not exist */
3462 /* then case is out of context */
3465 werror (E_CASE_CONTEXT);
3469 caseVal = decorateType (resolveSymbols (caseVal));
3470 /* if not a constant then error */
3471 if (!IS_LITERAL (caseVal->ftype))
3473 werror (E_CASE_CONSTANT);
3477 /* if not a integer than error */
3478 if (!IS_INTEGRAL (caseVal->ftype))
3480 werror (E_CASE_NON_INTEGER);
3484 /* find the end of the switch values chain */
3485 if (!(val = swStat->values.switchVals.swVals))
3486 swStat->values.switchVals.swVals = caseVal->opval.val;
3489 /* also order the cases according to value */
3491 int cVal = (int) floatFromVal (caseVal->opval.val);
3492 while (val && (int) floatFromVal (val) < cVal)
3498 /* if we reached the end then */
3501 pval->next = caseVal->opval.val;
3505 /* we found a value greater than */
3506 /* the current value we must add this */
3507 /* before the value */
3508 caseVal->opval.val->next = val;
3510 /* if this was the first in chain */
3511 if (swStat->values.switchVals.swVals == val)
3512 swStat->values.switchVals.swVals =
3515 pval->next = caseVal->opval.val;
3520 /* create the case label */
3521 sprintf (caseLbl, "_case_%d_%d",
3522 swStat->values.switchVals.swNum,
3523 (int) floatFromVal (caseVal->opval.val));
3525 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3530 /*-----------------------------------------------------------------*/
3531 /* createDefault - creates the parse tree for the default statement */
3532 /*-----------------------------------------------------------------*/
3534 createDefault (ast * swStat, ast * stmnt)
3536 char defLbl[SDCC_NAME_MAX + 1];
3538 /* if the switch statement does not exist */
3539 /* then case is out of context */
3542 werror (E_CASE_CONTEXT);
3546 /* turn on the default flag */
3547 swStat->values.switchVals.swDefault = 1;
3549 /* create the label */
3550 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3551 return createLabel (newSymbol (defLbl, 0), stmnt);
3554 /*-----------------------------------------------------------------*/
3555 /* createIf - creates the parsetree for the if statement */
3556 /*-----------------------------------------------------------------*/
3558 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3560 static int Lblnum = 0;
3562 symbol *ifTrue, *ifFalse, *ifEnd;
3564 /* if neither exists */
3565 if (!elseBody && !ifBody) {
3566 // if there are no side effects (i++, j() etc)
3567 if (!hasSEFcalls(condAst)) {
3572 /* create the labels */
3573 sprintf (buffer, "_iffalse_%d", Lblnum);
3574 ifFalse = newSymbol (buffer, NestLevel);
3575 /* if no else body then end == false */
3580 sprintf (buffer, "_ifend_%d", Lblnum);
3581 ifEnd = newSymbol (buffer, NestLevel);
3584 sprintf (buffer, "_iftrue_%d", Lblnum);
3585 ifTrue = newSymbol (buffer, NestLevel);
3589 /* attach the ifTrue label to the top of it body */
3590 ifBody = createLabel (ifTrue, ifBody);
3591 /* attach a goto end to the ifBody if else is present */
3594 ifBody = newNode (NULLOP, ifBody,
3596 newAst_VALUE (symbolVal (ifEnd)),
3598 /* put the elseLabel on the else body */
3599 elseBody = createLabel (ifFalse, elseBody);
3600 /* out the end at the end of the body */
3601 elseBody = newNode (NULLOP,
3603 createLabel (ifEnd, NULL));
3607 ifBody = newNode (NULLOP, ifBody,
3608 createLabel (ifFalse, NULL));
3610 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3611 if (IS_IFX (condAst))
3614 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3616 return newNode (NULLOP, ifTree,
3617 newNode (NULLOP, ifBody, elseBody));
3621 /*-----------------------------------------------------------------*/
3622 /* createDo - creates parse tree for do */
3625 /* _docontinue_n: */
3626 /* condition_expression +-> trueLabel -> _dobody_n */
3628 /* +-> falseLabel-> _dobreak_n */
3630 /*-----------------------------------------------------------------*/
3632 createDo (symbol * trueLabel, symbol * continueLabel,
3633 symbol * falseLabel, ast * condAst, ast * doBody)
3638 /* if the body does not exist then it is simple */
3641 condAst = backPatchLabels (condAst, continueLabel, NULL);
3642 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3643 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3644 doTree->trueLabel = continueLabel;
3645 doTree->falseLabel = NULL;
3649 /* otherwise we have a body */
3650 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3652 /* attach the body label to the top */
3653 doBody = createLabel (trueLabel, doBody);
3654 /* attach the continue label to end of body */
3655 doBody = newNode (NULLOP, doBody,
3656 createLabel (continueLabel, NULL));
3658 /* now put the break label at the end */
3659 if (IS_IFX (condAst))
3662 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3664 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3666 /* putting it together */
3667 return newNode (NULLOP, doBody, doTree);
3670 /*-----------------------------------------------------------------*/
3671 /* createFor - creates parse tree for 'for' statement */
3674 /* condExpr +-> trueLabel -> _forbody_n */
3676 /* +-> falseLabel-> _forbreak_n */
3679 /* _forcontinue_n: */
3681 /* goto _forcond_n ; */
3683 /*-----------------------------------------------------------------*/
3685 createFor (symbol * trueLabel, symbol * continueLabel,
3686 symbol * falseLabel, symbol * condLabel,
3687 ast * initExpr, ast * condExpr, ast * loopExpr,
3692 /* if loopexpression not present then we can generate it */
3693 /* the same way as a while */
3695 return newNode (NULLOP, initExpr,
3696 createWhile (trueLabel, continueLabel,
3697 falseLabel, condExpr, forBody));
3698 /* vanilla for statement */
3699 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3701 if (condExpr && !IS_IFX (condExpr))
3702 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3705 /* attach condition label to condition */
3706 condExpr = createLabel (condLabel, condExpr);
3708 /* attach body label to body */
3709 forBody = createLabel (trueLabel, forBody);
3711 /* attach continue to forLoop expression & attach */
3712 /* goto the forcond @ and of loopExpression */
3713 loopExpr = createLabel (continueLabel,
3717 newAst_VALUE (symbolVal (condLabel)),
3719 /* now start putting them together */
3720 forTree = newNode (NULLOP, initExpr, condExpr);
3721 forTree = newNode (NULLOP, forTree, forBody);
3722 forTree = newNode (NULLOP, forTree, loopExpr);
3723 /* finally add the break label */
3724 forTree = newNode (NULLOP, forTree,
3725 createLabel (falseLabel, NULL));
3729 /*-----------------------------------------------------------------*/
3730 /* createWhile - creates parse tree for while statement */
3731 /* the while statement will be created as follows */
3733 /* _while_continue_n: */
3734 /* condition_expression +-> trueLabel -> _while_boby_n */
3736 /* +-> falseLabel -> _while_break_n */
3737 /* _while_body_n: */
3739 /* goto _while_continue_n */
3740 /* _while_break_n: */
3741 /*-----------------------------------------------------------------*/
3743 createWhile (symbol * trueLabel, symbol * continueLabel,
3744 symbol * falseLabel, ast * condExpr, ast * whileBody)
3748 /* put the continue label */
3749 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3750 condExpr = createLabel (continueLabel, condExpr);
3751 condExpr->lineno = 0;
3753 /* put the body label in front of the body */
3754 whileBody = createLabel (trueLabel, whileBody);
3755 whileBody->lineno = 0;
3756 /* put a jump to continue at the end of the body */
3757 /* and put break label at the end of the body */
3758 whileBody = newNode (NULLOP,
3761 newAst_VALUE (symbolVal (continueLabel)),
3762 createLabel (falseLabel, NULL)));
3764 /* put it all together */
3765 if (IS_IFX (condExpr))
3766 whileTree = condExpr;
3769 whileTree = newNode (IFX, condExpr, NULL);
3770 /* put the true & false labels in place */
3771 whileTree->trueLabel = trueLabel;
3772 whileTree->falseLabel = falseLabel;
3775 return newNode (NULLOP, whileTree, whileBody);
3778 /*-----------------------------------------------------------------*/
3779 /* optimizeGetHbit - get highest order bit of the expression */
3780 /*-----------------------------------------------------------------*/
3782 optimizeGetHbit (ast * tree)
3785 /* if this is not a bit and */
3786 if (!IS_BITAND (tree))
3789 /* will look for tree of the form
3790 ( expr >> ((sizeof expr) -1) ) & 1 */
3791 if (!IS_AST_LIT_VALUE (tree->right))
3794 if (AST_LIT_VALUE (tree->right) != 1)
3797 if (!IS_RIGHT_OP (tree->left))
3800 if (!IS_AST_LIT_VALUE (tree->left->right))
3803 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3804 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3807 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3811 /*-----------------------------------------------------------------*/
3812 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3813 /*-----------------------------------------------------------------*/
3815 optimizeRRCRLC (ast * root)
3817 /* will look for trees of the form
3818 (?expr << 1) | (?expr >> 7) or
3819 (?expr >> 7) | (?expr << 1) will make that
3820 into a RLC : operation ..
3822 (?expr >> 1) | (?expr << 7) or
3823 (?expr << 7) | (?expr >> 1) will make that
3824 into a RRC operation
3825 note : by 7 I mean (number of bits required to hold the
3827 /* if the root operations is not a | operation the not */
3828 if (!IS_BITOR (root))
3831 /* I have to think of a better way to match patterns this sucks */
3832 /* that aside let start looking for the first case : I use a the
3833 negative check a lot to improve the efficiency */
3834 /* (?expr << 1) | (?expr >> 7) */
3835 if (IS_LEFT_OP (root->left) &&
3836 IS_RIGHT_OP (root->right))
3839 if (!SPEC_USIGN (TETYPE (root->left->left)))
3842 if (!IS_AST_LIT_VALUE (root->left->right) ||
3843 !IS_AST_LIT_VALUE (root->right->right))
3846 /* make sure it is the same expression */
3847 if (!isAstEqual (root->left->left,
3851 if (AST_LIT_VALUE (root->left->right) != 1)
3854 if (AST_LIT_VALUE (root->right->right) !=
3855 (getSize (TTYPE (root->left->left)) * 8 - 1))
3858 /* whew got the first case : create the AST */
3859 return newNode (RLC, root->left->left, NULL);
3863 /* check for second case */
3864 /* (?expr >> 7) | (?expr << 1) */
3865 if (IS_LEFT_OP (root->right) &&
3866 IS_RIGHT_OP (root->left))
3869 if (!SPEC_USIGN (TETYPE (root->left->left)))
3872 if (!IS_AST_LIT_VALUE (root->left->right) ||
3873 !IS_AST_LIT_VALUE (root->right->right))
3876 /* make sure it is the same symbol */
3877 if (!isAstEqual (root->left->left,
3881 if (AST_LIT_VALUE (root->right->right) != 1)
3884 if (AST_LIT_VALUE (root->left->right) !=
3885 (getSize (TTYPE (root->left->left)) * 8 - 1))
3888 /* whew got the first case : create the AST */
3889 return newNode (RLC, root->left->left, NULL);
3894 /* third case for RRC */
3895 /* (?symbol >> 1) | (?symbol << 7) */
3896 if (IS_LEFT_OP (root->right) &&
3897 IS_RIGHT_OP (root->left))
3900 if (!SPEC_USIGN (TETYPE (root->left->left)))
3903 if (!IS_AST_LIT_VALUE (root->left->right) ||
3904 !IS_AST_LIT_VALUE (root->right->right))
3907 /* make sure it is the same symbol */
3908 if (!isAstEqual (root->left->left,
3912 if (AST_LIT_VALUE (root->left->right) != 1)
3915 if (AST_LIT_VALUE (root->right->right) !=
3916 (getSize (TTYPE (root->left->left)) * 8 - 1))
3919 /* whew got the first case : create the AST */
3920 return newNode (RRC, root->left->left, NULL);
3924 /* fourth and last case for now */
3925 /* (?symbol << 7) | (?symbol >> 1) */
3926 if (IS_RIGHT_OP (root->right) &&
3927 IS_LEFT_OP (root->left))
3930 if (!SPEC_USIGN (TETYPE (root->left->left)))
3933 if (!IS_AST_LIT_VALUE (root->left->right) ||
3934 !IS_AST_LIT_VALUE (root->right->right))
3937 /* make sure it is the same symbol */
3938 if (!isAstEqual (root->left->left,
3942 if (AST_LIT_VALUE (root->right->right) != 1)
3945 if (AST_LIT_VALUE (root->left->right) !=
3946 (getSize (TTYPE (root->left->left)) * 8 - 1))
3949 /* whew got the first case : create the AST */
3950 return newNode (RRC, root->left->left, NULL);
3954 /* not found return root */
3958 /*-----------------------------------------------------------------*/
3959 /* optimizeCompare - otimizes compares for bit variables */
3960 /*-----------------------------------------------------------------*/
3962 optimizeCompare (ast * root)
3964 ast *optExpr = NULL;
3967 unsigned int litValue;
3969 /* if nothing then return nothing */
3973 /* if not a compare op then do leaves */
3974 if (!IS_COMPARE_OP (root))
3976 root->left = optimizeCompare (root->left);
3977 root->right = optimizeCompare (root->right);
3981 /* if left & right are the same then depending
3982 of the operation do */
3983 if (isAstEqual (root->left, root->right))
3985 switch (root->opval.op)
3990 optExpr = newAst_VALUE (constVal ("0"));
3995 optExpr = newAst_VALUE (constVal ("1"));
3999 return decorateType (optExpr);
4002 vleft = (root->left->type == EX_VALUE ?
4003 root->left->opval.val : NULL);
4005 vright = (root->right->type == EX_VALUE ?
4006 root->right->opval.val : NULL);
4008 /* if left is a BITVAR in BITSPACE */
4009 /* and right is a LITERAL then opt- */
4010 /* imize else do nothing */
4011 if (vleft && vright &&
4012 IS_BITVAR (vleft->etype) &&
4013 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4014 IS_LITERAL (vright->etype))
4017 /* if right side > 1 then comparison may never succeed */
4018 if ((litValue = (int) floatFromVal (vright)) > 1)
4020 werror (W_BAD_COMPARE);
4026 switch (root->opval.op)
4028 case '>': /* bit value greater than 1 cannot be */
4029 werror (W_BAD_COMPARE);
4033 case '<': /* bit value < 1 means 0 */
4035 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4038 case LE_OP: /* bit value <= 1 means no check */
4039 optExpr = newAst_VALUE (vright);
4042 case GE_OP: /* bit value >= 1 means only check for = */
4044 optExpr = newAst_VALUE (vleft);
4049 { /* literal is zero */
4050 switch (root->opval.op)
4052 case '<': /* bit value < 0 cannot be */
4053 werror (W_BAD_COMPARE);
4057 case '>': /* bit value > 0 means 1 */
4059 optExpr = newAst_VALUE (vleft);
4062 case LE_OP: /* bit value <= 0 means no check */
4063 case GE_OP: /* bit value >= 0 means no check */
4064 werror (W_BAD_COMPARE);
4068 case EQ_OP: /* bit == 0 means ! of bit */
4069 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4073 return decorateType (resolveSymbols (optExpr));
4074 } /* end-of-if of BITVAR */
4079 /*-----------------------------------------------------------------*/
4080 /* addSymToBlock : adds the symbol to the first block we find */
4081 /*-----------------------------------------------------------------*/
4083 addSymToBlock (symbol * sym, ast * tree)
4085 /* reached end of tree or a leaf */
4086 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4090 if (IS_AST_OP (tree) &&
4091 tree->opval.op == BLOCK)
4094 symbol *lsym = copySymbol (sym);
4096 lsym->next = AST_VALUES (tree, sym);
4097 AST_VALUES (tree, sym) = lsym;
4101 addSymToBlock (sym, tree->left);
4102 addSymToBlock (sym, tree->right);
4105 /*-----------------------------------------------------------------*/
4106 /* processRegParms - do processing for register parameters */
4107 /*-----------------------------------------------------------------*/
4109 processRegParms (value * args, ast * body)
4113 if (IS_REGPARM (args->etype))
4114 addSymToBlock (args->sym, body);
4119 /*-----------------------------------------------------------------*/
4120 /* resetParmKey - resets the operandkeys for the symbols */
4121 /*-----------------------------------------------------------------*/
4122 DEFSETFUNC (resetParmKey)
4133 /*-----------------------------------------------------------------*/
4134 /* createFunction - This is the key node that calls the iCode for */
4135 /* generating the code for a function. Note code */
4136 /* is generated function by function, later when */
4137 /* add inter-procedural analysis this will change */
4138 /*-----------------------------------------------------------------*/
4140 createFunction (symbol * name, ast * body)
4146 iCode *piCode = NULL;
4148 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4149 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4151 /* if check function return 0 then some problem */
4152 if (checkFunction (name, NULL) == 0)
4155 /* create a dummy block if none exists */
4157 body = newNode (BLOCK, NULL, NULL);
4161 /* check if the function name already in the symbol table */
4162 if ((csym = findSym (SymbolTab, NULL, name->name)))
4165 /* special case for compiler defined functions
4166 we need to add the name to the publics list : this
4167 actually means we are now compiling the compiler
4171 addSet (&publics, name);
4177 allocVariables (name);
4179 name->lastLine = yylineno;
4182 /* set the stack pointer */
4183 /* PENDING: check this for the mcs51 */
4184 stackPtr = -port->stack.direction * port->stack.call_overhead;
4185 if (IFFUNC_ISISR (name->type))
4186 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4187 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4188 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4190 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4192 fetype = getSpec (name->type); /* get the specifier for the function */
4193 /* if this is a reentrant function then */
4194 if (IFFUNC_ISREENT (name->type))
4197 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4199 /* do processing for parameters that are passed in registers */
4200 processRegParms (FUNC_ARGS(name->type), body);
4202 /* set the stack pointer */
4206 /* allocate & autoinit the block variables */
4207 processBlockVars (body, &stack, ALLOCATE);
4209 /* save the stack information */
4210 if (options.useXstack)
4211 name->xstack = SPEC_STAK (fetype) = stack;
4213 name->stack = SPEC_STAK (fetype) = stack;
4215 /* name needs to be mangled */
4216 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4218 body = resolveSymbols (body); /* resolve the symbols */
4219 body = decorateType (body); /* propagateType & do semantic checks */
4221 ex = newAst_VALUE (symbolVal (name)); /* create name */
4222 ex = newNode (FUNCTION, ex, body);
4223 ex->values.args = FUNC_ARGS(name->type);
4225 if (options.dump_tree) PA(ex);
4228 werror (E_FUNC_NO_CODE, name->name);
4232 /* create the node & generate intermediate code */
4234 codeOutFile = code->oFile;
4235 piCode = iCodeFromAst (ex);
4239 werror (E_FUNC_NO_CODE, name->name);
4243 eBBlockFromiCode (piCode);
4245 /* if there are any statics then do them */
4248 GcurMemmap = statsg;
4249 codeOutFile = statsg->oFile;
4250 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4256 /* dealloc the block variables */
4257 processBlockVars (body, &stack, DEALLOCATE);
4258 /* deallocate paramaters */
4259 deallocParms (FUNC_ARGS(name->type));
4261 if (IFFUNC_ISREENT (name->type))
4264 /* we are done freeup memory & cleanup */
4266 if (port->reset_labelKey) labelKey = 1;
4268 FUNC_HASBODY(name->type) = 1;
4269 addSet (&operKeyReset, name);
4270 applyToSet (operKeyReset, resetParmKey);
4273 cdbStructBlock (1, cdbFile);
4275 cleanUpLevel (LabelTab, 0);
4276 cleanUpBlock (StructTab, 1);
4277 cleanUpBlock (TypedefTab, 1);
4279 xstack->syms = NULL;
4280 istack->syms = NULL;
4285 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4286 /*-----------------------------------------------------------------*/
4287 /* ast_print : prints the ast (for debugging purposes) */
4288 /*-----------------------------------------------------------------*/
4290 void ast_print (ast * tree, FILE *outfile, int indent)
4295 /* can print only decorated trees */
4296 if (!tree->decorated) return;
4298 /* if any child is an error | this one is an error do nothing */
4299 if (tree->isError ||
4300 (tree->left && tree->left->isError) ||
4301 (tree->right && tree->right->isError)) {
4302 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4306 /* print the line */
4307 /* if not block & function */
4308 if (tree->type == EX_OP &&
4309 (tree->opval.op != FUNCTION &&
4310 tree->opval.op != BLOCK &&
4311 tree->opval.op != NULLOP)) {
4314 if (tree->opval.op == FUNCTION) {
4316 value *args=FUNC_ARGS(tree->left->opval.val->type);
4317 fprintf(outfile,"FUNCTION (%s=%p) type (",
4318 tree->left->opval.val->name, tree);
4319 printTypeChain (tree->ftype,outfile);
4320 fprintf(outfile,") args (");
4323 fprintf (outfile, ", ");
4325 printTypeChain (args ? args->type : NULL, outfile);
4327 args= args ? args->next : NULL;
4329 fprintf(outfile,")\n");
4330 ast_print(tree->left,outfile,indent);
4331 ast_print(tree->right,outfile,indent);
4334 if (tree->opval.op == BLOCK) {
4335 symbol *decls = tree->values.sym;
4336 INDENT(indent,outfile);
4337 fprintf(outfile,"{\n");
4339 INDENT(indent+2,outfile);
4340 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4341 decls->name, decls);
4342 printTypeChain(decls->type,outfile);
4343 fprintf(outfile,")\n");
4345 decls = decls->next;
4347 ast_print(tree->right,outfile,indent+2);
4348 INDENT(indent,outfile);
4349 fprintf(outfile,"}\n");
4352 if (tree->opval.op == NULLOP) {
4353 fprintf(outfile,"\n");
4354 ast_print(tree->left,outfile,indent);
4355 fprintf(outfile,"\n");
4356 ast_print(tree->right,outfile,indent);
4359 INDENT(indent,outfile);
4361 /*------------------------------------------------------------------*/
4362 /*----------------------------*/
4363 /* leaf has been reached */
4364 /*----------------------------*/
4365 /* if this is of type value */
4366 /* just get the type */
4367 if (tree->type == EX_VALUE) {
4369 if (IS_LITERAL (tree->opval.val->etype)) {
4370 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4371 (int) floatFromVal(tree->opval.val),
4372 (int) floatFromVal(tree->opval.val),
4373 floatFromVal(tree->opval.val));
4374 } else if (tree->opval.val->sym) {
4375 /* if the undefined flag is set then give error message */
4376 if (tree->opval.val->sym->undefined) {
4377 fprintf(outfile,"UNDEFINED SYMBOL ");
4379 fprintf(outfile,"SYMBOL ");
4381 fprintf(outfile,"(%s=%p)",
4382 tree->opval.val->sym->name,tree);
4385 fprintf(outfile," type (");
4386 printTypeChain(tree->ftype,outfile);
4387 fprintf(outfile,")\n");
4389 fprintf(outfile,"\n");
4394 /* if type link for the case of cast */
4395 if (tree->type == EX_LINK) {
4396 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4397 printTypeChain(tree->opval.lnk,outfile);
4398 fprintf(outfile,")\n");
4403 /* depending on type of operator do */
4405 switch (tree->opval.op) {
4406 /*------------------------------------------------------------------*/
4407 /*----------------------------*/
4409 /*----------------------------*/
4411 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4412 printTypeChain(tree->ftype,outfile);
4413 fprintf(outfile,")\n");
4414 ast_print(tree->left,outfile,indent+2);
4415 ast_print(tree->right,outfile,indent+2);
4418 /*------------------------------------------------------------------*/
4419 /*----------------------------*/
4421 /*----------------------------*/
4423 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4424 printTypeChain(tree->ftype,outfile);
4425 fprintf(outfile,")\n");
4426 ast_print(tree->left,outfile,indent+2);
4427 ast_print(tree->right,outfile,indent+2);
4430 /*------------------------------------------------------------------*/
4431 /*----------------------------*/
4432 /* struct/union pointer */
4433 /*----------------------------*/
4435 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4436 printTypeChain(tree->ftype,outfile);
4437 fprintf(outfile,")\n");
4438 ast_print(tree->left,outfile,indent+2);
4439 ast_print(tree->right,outfile,indent+2);
4442 /*------------------------------------------------------------------*/
4443 /*----------------------------*/
4444 /* ++/-- operation */
4445 /*----------------------------*/
4446 case INC_OP: /* incerement operator unary so left only */
4447 fprintf(outfile,"INC_OP (%p) type (",tree);
4448 printTypeChain(tree->ftype,outfile);
4449 fprintf(outfile,")\n");
4450 ast_print(tree->left,outfile,indent+2);
4454 fprintf(outfile,"DEC_OP (%p) type (",tree);
4455 printTypeChain(tree->ftype,outfile);
4456 fprintf(outfile,")\n");
4457 ast_print(tree->left,outfile,indent+2);
4460 /*------------------------------------------------------------------*/
4461 /*----------------------------*/
4463 /*----------------------------*/
4466 fprintf(outfile,"& (%p) type (",tree);
4467 printTypeChain(tree->ftype,outfile);
4468 fprintf(outfile,")\n");
4469 ast_print(tree->left,outfile,indent+2);
4470 ast_print(tree->right,outfile,indent+2);
4472 fprintf(outfile,"ADDRESS_OF (%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);
4479 /*----------------------------*/
4481 /*----------------------------*/
4483 fprintf(outfile,"OR (%p) type (",tree);
4484 printTypeChain(tree->ftype,outfile);
4485 fprintf(outfile,")\n");
4486 ast_print(tree->left,outfile,indent+2);
4487 ast_print(tree->right,outfile,indent+2);
4489 /*------------------------------------------------------------------*/
4490 /*----------------------------*/
4492 /*----------------------------*/
4494 fprintf(outfile,"XOR (%p) type (",tree);
4495 printTypeChain(tree->ftype,outfile);
4496 fprintf(outfile,")\n");
4497 ast_print(tree->left,outfile,indent+2);
4498 ast_print(tree->right,outfile,indent+2);
4501 /*------------------------------------------------------------------*/
4502 /*----------------------------*/
4504 /*----------------------------*/
4506 fprintf(outfile,"DIV (%p) type (",tree);
4507 printTypeChain(tree->ftype,outfile);
4508 fprintf(outfile,")\n");
4509 ast_print(tree->left,outfile,indent+2);
4510 ast_print(tree->right,outfile,indent+2);
4512 /*------------------------------------------------------------------*/
4513 /*----------------------------*/
4515 /*----------------------------*/
4517 fprintf(outfile,"MOD (%p) type (",tree);
4518 printTypeChain(tree->ftype,outfile);
4519 fprintf(outfile,")\n");
4520 ast_print(tree->left,outfile,indent+2);
4521 ast_print(tree->right,outfile,indent+2);
4524 /*------------------------------------------------------------------*/
4525 /*----------------------------*/
4526 /* address dereference */
4527 /*----------------------------*/
4528 case '*': /* can be unary : if right is null then unary operation */
4530 fprintf(outfile,"DEREF (%p) type (",tree);
4531 printTypeChain(tree->ftype,outfile);
4532 fprintf(outfile,")\n");
4533 ast_print(tree->left,outfile,indent+2);
4536 /*------------------------------------------------------------------*/
4537 /*----------------------------*/
4538 /* multiplication */
4539 /*----------------------------*/
4540 fprintf(outfile,"MULT (%p) type (",tree);
4541 printTypeChain(tree->ftype,outfile);
4542 fprintf(outfile,")\n");
4543 ast_print(tree->left,outfile,indent+2);
4544 ast_print(tree->right,outfile,indent+2);
4548 /*------------------------------------------------------------------*/
4549 /*----------------------------*/
4550 /* unary '+' operator */
4551 /*----------------------------*/
4555 fprintf(outfile,"UPLUS (%p) type (",tree);
4556 printTypeChain(tree->ftype,outfile);
4557 fprintf(outfile,")\n");
4558 ast_print(tree->left,outfile,indent+2);
4560 /*------------------------------------------------------------------*/
4561 /*----------------------------*/
4563 /*----------------------------*/
4564 fprintf(outfile,"ADD (%p) type (",tree);
4565 printTypeChain(tree->ftype,outfile);
4566 fprintf(outfile,")\n");
4567 ast_print(tree->left,outfile,indent+2);
4568 ast_print(tree->right,outfile,indent+2);
4571 /*------------------------------------------------------------------*/
4572 /*----------------------------*/
4574 /*----------------------------*/
4575 case '-': /* can be unary */
4577 fprintf(outfile,"UMINUS (%p) type (",tree);
4578 printTypeChain(tree->ftype,outfile);
4579 fprintf(outfile,")\n");
4580 ast_print(tree->left,outfile,indent+2);
4582 /*------------------------------------------------------------------*/
4583 /*----------------------------*/
4585 /*----------------------------*/
4586 fprintf(outfile,"SUB (%p) type (",tree);
4587 printTypeChain(tree->ftype,outfile);
4588 fprintf(outfile,")\n");
4589 ast_print(tree->left,outfile,indent+2);
4590 ast_print(tree->right,outfile,indent+2);
4593 /*------------------------------------------------------------------*/
4594 /*----------------------------*/
4596 /*----------------------------*/
4598 fprintf(outfile,"COMPL (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+2);
4603 /*------------------------------------------------------------------*/
4604 /*----------------------------*/
4606 /*----------------------------*/
4608 fprintf(outfile,"NOT (%p) type (",tree);
4609 printTypeChain(tree->ftype,outfile);
4610 fprintf(outfile,")\n");
4611 ast_print(tree->left,outfile,indent+2);
4613 /*------------------------------------------------------------------*/
4614 /*----------------------------*/
4616 /*----------------------------*/
4618 fprintf(outfile,"RRC (%p) type (",tree);
4619 printTypeChain(tree->ftype,outfile);
4620 fprintf(outfile,")\n");
4621 ast_print(tree->left,outfile,indent+2);
4625 fprintf(outfile,"RLC (%p) type (",tree);
4626 printTypeChain(tree->ftype,outfile);
4627 fprintf(outfile,")\n");
4628 ast_print(tree->left,outfile,indent+2);
4631 fprintf(outfile,"GETHBIT (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+2);
4637 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4638 printTypeChain(tree->ftype,outfile);
4639 fprintf(outfile,")\n");
4640 ast_print(tree->left,outfile,indent+2);
4641 ast_print(tree->right,outfile,indent+2);
4644 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4645 printTypeChain(tree->ftype,outfile);
4646 fprintf(outfile,")\n");
4647 ast_print(tree->left,outfile,indent+2);
4648 ast_print(tree->right,outfile,indent+2);
4650 /*------------------------------------------------------------------*/
4651 /*----------------------------*/
4653 /*----------------------------*/
4654 case CAST: /* change the type */
4655 fprintf(outfile,"CAST (%p) from type (",tree);
4656 printTypeChain(tree->right->ftype,outfile);
4657 fprintf(outfile,") to type (");
4658 printTypeChain(tree->ftype,outfile);
4659 fprintf(outfile,")\n");
4660 ast_print(tree->right,outfile,indent+2);
4664 fprintf(outfile,"ANDAND (%p) type (",tree);
4665 printTypeChain(tree->ftype,outfile);
4666 fprintf(outfile,")\n");
4667 ast_print(tree->left,outfile,indent+2);
4668 ast_print(tree->right,outfile,indent+2);
4671 fprintf(outfile,"OROR (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+2);
4675 ast_print(tree->right,outfile,indent+2);
4678 /*------------------------------------------------------------------*/
4679 /*----------------------------*/
4680 /* comparison operators */
4681 /*----------------------------*/
4683 fprintf(outfile,"GT(>) (%p) type (",tree);
4684 printTypeChain(tree->ftype,outfile);
4685 fprintf(outfile,")\n");
4686 ast_print(tree->left,outfile,indent+2);
4687 ast_print(tree->right,outfile,indent+2);
4690 fprintf(outfile,"LT(<) (%p) type (",tree);
4691 printTypeChain(tree->ftype,outfile);
4692 fprintf(outfile,")\n");
4693 ast_print(tree->left,outfile,indent+2);
4694 ast_print(tree->right,outfile,indent+2);
4697 fprintf(outfile,"LE(<=) (%p) type (",tree);
4698 printTypeChain(tree->ftype,outfile);
4699 fprintf(outfile,")\n");
4700 ast_print(tree->left,outfile,indent+2);
4701 ast_print(tree->right,outfile,indent+2);
4704 fprintf(outfile,"GE(>=) (%p) type (",tree);
4705 printTypeChain(tree->ftype,outfile);
4706 fprintf(outfile,")\n");
4707 ast_print(tree->left,outfile,indent+2);
4708 ast_print(tree->right,outfile,indent+2);
4711 fprintf(outfile,"EQ(==) (%p) type (",tree);
4712 printTypeChain(tree->ftype,outfile);
4713 fprintf(outfile,")\n");
4714 ast_print(tree->left,outfile,indent+2);
4715 ast_print(tree->right,outfile,indent+2);
4718 fprintf(outfile,"NE(!=) (%p) type (",tree);
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->left,outfile,indent+2);
4722 ast_print(tree->right,outfile,indent+2);
4723 /*------------------------------------------------------------------*/
4724 /*----------------------------*/
4726 /*----------------------------*/
4727 case SIZEOF: /* evaluate wihout code generation */
4728 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4731 /*------------------------------------------------------------------*/
4732 /*----------------------------*/
4733 /* conditional operator '?' */
4734 /*----------------------------*/
4736 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4737 printTypeChain(tree->ftype,outfile);
4738 fprintf(outfile,")\n");
4739 ast_print(tree->left,outfile,indent+2);
4740 ast_print(tree->right,outfile,indent+2);
4744 fprintf(outfile,"COLON(:) (%p) type (",tree);
4745 printTypeChain(tree->ftype,outfile);
4746 fprintf(outfile,")\n");
4747 ast_print(tree->left,outfile,indent+2);
4748 ast_print(tree->right,outfile,indent+2);
4751 /*------------------------------------------------------------------*/
4752 /*----------------------------*/
4753 /* assignment operators */
4754 /*----------------------------*/
4756 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4757 printTypeChain(tree->ftype,outfile);
4758 fprintf(outfile,")\n");
4759 ast_print(tree->left,outfile,indent+2);
4760 ast_print(tree->right,outfile,indent+2);
4763 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+2);
4767 ast_print(tree->right,outfile,indent+2);
4770 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4771 printTypeChain(tree->ftype,outfile);
4772 fprintf(outfile,")\n");
4773 ast_print(tree->left,outfile,indent+2);
4774 ast_print(tree->right,outfile,indent+2);
4777 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4778 printTypeChain(tree->ftype,outfile);
4779 fprintf(outfile,")\n");
4780 ast_print(tree->left,outfile,indent+2);
4781 ast_print(tree->right,outfile,indent+2);
4784 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4785 printTypeChain(tree->ftype,outfile);
4786 fprintf(outfile,")\n");
4787 ast_print(tree->left,outfile,indent+2);
4788 ast_print(tree->right,outfile,indent+2);
4791 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4792 printTypeChain(tree->ftype,outfile);
4793 fprintf(outfile,")\n");
4794 ast_print(tree->left,outfile,indent+2);
4795 ast_print(tree->right,outfile,indent+2);
4798 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4799 printTypeChain(tree->ftype,outfile);
4800 fprintf(outfile,")\n");
4801 ast_print(tree->left,outfile,indent+2);
4802 ast_print(tree->right,outfile,indent+2);
4804 /*------------------------------------------------------------------*/
4805 /*----------------------------*/
4807 /*----------------------------*/
4809 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4810 printTypeChain(tree->ftype,outfile);
4811 fprintf(outfile,")\n");
4812 ast_print(tree->left,outfile,indent+2);
4813 ast_print(tree->right,outfile,indent+2);
4815 /*------------------------------------------------------------------*/
4816 /*----------------------------*/
4818 /*----------------------------*/
4820 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4821 printTypeChain(tree->ftype,outfile);
4822 fprintf(outfile,")\n");
4823 ast_print(tree->left,outfile,indent+2);
4824 ast_print(tree->right,outfile,indent+2);
4826 /*------------------------------------------------------------------*/
4827 /*----------------------------*/
4828 /* straight assignemnt */
4829 /*----------------------------*/
4831 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4832 printTypeChain(tree->ftype,outfile);
4833 fprintf(outfile,")\n");
4834 ast_print(tree->left,outfile,indent+2);
4835 ast_print(tree->right,outfile,indent+2);
4837 /*------------------------------------------------------------------*/
4838 /*----------------------------*/
4839 /* comma operator */
4840 /*----------------------------*/
4842 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4843 printTypeChain(tree->ftype,outfile);
4844 fprintf(outfile,")\n");
4845 ast_print(tree->left,outfile,indent+2);
4846 ast_print(tree->right,outfile,indent+2);
4848 /*------------------------------------------------------------------*/
4849 /*----------------------------*/
4851 /*----------------------------*/
4854 fprintf(outfile,"CALL (%p) type (",tree);
4855 printTypeChain(tree->ftype,outfile);
4856 fprintf(outfile,")\n");
4857 ast_print(tree->left,outfile,indent+2);
4858 ast_print(tree->right,outfile,indent+2);
4861 fprintf(outfile,"PARMS\n");
4862 ast_print(tree->left,outfile,indent+2);
4863 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4864 ast_print(tree->right,outfile,indent+2);
4867 /*------------------------------------------------------------------*/
4868 /*----------------------------*/
4869 /* return statement */
4870 /*----------------------------*/
4872 fprintf(outfile,"RETURN (%p) type (",tree);
4873 printTypeChain(tree->right->ftype,outfile);
4874 fprintf(outfile,")\n");
4875 ast_print(tree->right,outfile,indent+2);
4877 /*------------------------------------------------------------------*/
4878 /*----------------------------*/
4879 /* label statement */
4880 /*----------------------------*/
4882 fprintf(outfile,"LABEL (%p)\n",tree);
4883 ast_print(tree->left,outfile,indent+2);
4884 ast_print(tree->right,outfile,indent);
4886 /*------------------------------------------------------------------*/
4887 /*----------------------------*/
4888 /* switch statement */
4889 /*----------------------------*/
4893 fprintf(outfile,"SWITCH (%p) ",tree);
4894 ast_print(tree->left,outfile,0);
4895 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4896 INDENT(indent+2,outfile);
4897 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4898 (int) floatFromVal(val),
4899 tree->values.switchVals.swNum,
4900 (int) floatFromVal(val));
4902 ast_print(tree->right,outfile,indent);
4905 /*------------------------------------------------------------------*/
4906 /*----------------------------*/
4908 /*----------------------------*/
4910 fprintf(outfile,"IF (%p) \n",tree);
4911 ast_print(tree->left,outfile,indent+2);
4912 if (tree->trueLabel) {
4913 INDENT(indent,outfile);
4914 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4916 if (tree->falseLabel) {
4917 INDENT(indent,outfile);
4918 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4920 ast_print(tree->right,outfile,indent+2);
4922 /*------------------------------------------------------------------*/
4923 /*----------------------------*/
4925 /*----------------------------*/
4927 fprintf(outfile,"FOR (%p) \n",tree);
4928 if (AST_FOR( tree, initExpr)) {
4929 INDENT(indent+2,outfile);
4930 fprintf(outfile,"INIT EXPR ");
4931 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4933 if (AST_FOR( tree, condExpr)) {
4934 INDENT(indent+2,outfile);
4935 fprintf(outfile,"COND EXPR ");
4936 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4938 if (AST_FOR( tree, loopExpr)) {
4939 INDENT(indent+2,outfile);
4940 fprintf(outfile,"LOOP EXPR ");
4941 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4943 fprintf(outfile,"FOR LOOP BODY \n");
4944 ast_print(tree->left,outfile,indent+2);
4953 ast_print(t,stdout,0);