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 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
261 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
262 /*-----------------------------------------------------------------*/
263 ast *removeIncDecOps (ast * tree) {
265 // traverse the tree and remove inc/dec ops
270 if (tree->type == EX_OP &&
271 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
278 tree->left=removeIncDecOps(tree->left);
279 tree->right=removeIncDecOps(tree->right);
284 /*-----------------------------------------------------------------*/
285 /* hasSEFcalls - returns TRUE if tree has a function call */
286 /*-----------------------------------------------------------------*/
288 hasSEFcalls (ast * tree)
293 if (tree->type == EX_OP &&
294 (tree->opval.op == CALL ||
295 tree->opval.op == PCALL ||
296 tree->opval.op == '=' ||
297 tree->opval.op == INC_OP ||
298 tree->opval.op == DEC_OP))
301 return (hasSEFcalls (tree->left) |
302 hasSEFcalls (tree->right));
305 /*-----------------------------------------------------------------*/
306 /* isAstEqual - compares two asts & returns 1 if they are equal */
307 /*-----------------------------------------------------------------*/
309 isAstEqual (ast * t1, ast * t2)
318 if (t1->type != t2->type)
324 if (t1->opval.op != t2->opval.op)
326 return (isAstEqual (t1->left, t2->left) &&
327 isAstEqual (t1->right, t2->right));
331 if (t1->opval.val->sym)
333 if (!t2->opval.val->sym)
336 return isSymbolEqual (t1->opval.val->sym,
341 if (t2->opval.val->sym)
344 return (floatFromVal (t1->opval.val) ==
345 floatFromVal (t2->opval.val));
349 /* only compare these two types */
357 /*-----------------------------------------------------------------*/
358 /* resolveSymbols - resolve symbols from the symbol table */
359 /*-----------------------------------------------------------------*/
361 resolveSymbols (ast * tree)
363 /* walk the entire tree and check for values */
364 /* with symbols if we find one then replace */
365 /* symbol with that from the symbol table */
372 /* if not block & function */
373 if (tree->type == EX_OP &&
374 (tree->opval.op != FUNCTION &&
375 tree->opval.op != BLOCK &&
376 tree->opval.op != NULLOP))
378 filename = tree->filename;
379 lineno = tree->lineno;
383 /* make sure we resolve the true & false labels for ifx */
384 if (tree->type == EX_OP && tree->opval.op == IFX)
390 if ((csym = findSym (LabelTab, tree->trueLabel,
391 tree->trueLabel->name)))
392 tree->trueLabel = csym;
394 werror (E_LABEL_UNDEF, tree->trueLabel->name);
397 if (tree->falseLabel)
399 if ((csym = findSym (LabelTab,
401 tree->falseLabel->name)))
402 tree->falseLabel = csym;
404 werror (E_LABEL_UNDEF, tree->falseLabel->name);
409 /* if this is a label resolve it from the labelTab */
410 if (IS_AST_VALUE (tree) &&
411 tree->opval.val->sym &&
412 tree->opval.val->sym->islbl)
415 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
416 tree->opval.val->sym->name);
419 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
421 tree->opval.val->sym = csym;
423 goto resolveChildren;
426 /* do only for leafs */
427 if (IS_AST_VALUE (tree) &&
428 tree->opval.val->sym &&
429 !tree->opval.val->sym->implicit)
432 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
434 /* if found in the symbol table & they r not the same */
435 if (csym && tree->opval.val->sym != csym)
437 tree->opval.val->sym = csym;
438 tree->opval.val->type = csym->type;
439 tree->opval.val->etype = csym->etype;
442 /* if not found in the symbol table */
443 /* mark it as undefined assume it is */
444 /* an integer in data space */
445 if (!csym && !tree->opval.val->sym->implicit)
448 /* if this is a function name then */
449 /* mark it as returning an int */
452 tree->opval.val->sym->type = newLink ();
453 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
454 tree->opval.val->sym->type->next =
455 tree->opval.val->sym->etype = newIntLink ();
456 tree->opval.val->etype = tree->opval.val->etype;
457 tree->opval.val->type = tree->opval.val->sym->type;
458 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
459 allocVariables (tree->opval.val->sym);
463 tree->opval.val->sym->undefined = 1;
464 tree->opval.val->type =
465 tree->opval.val->etype = newIntLink ();
466 tree->opval.val->sym->type =
467 tree->opval.val->sym->etype = newIntLink ();
473 resolveSymbols (tree->left);
474 resolveSymbols (tree->right);
479 /*-----------------------------------------------------------------*/
480 /* setAstLineno - walks a ast tree & sets the line number */
481 /*-----------------------------------------------------------------*/
482 int setAstLineno (ast * tree, int lineno)
487 tree->lineno = lineno;
488 setAstLineno (tree->left, lineno);
489 setAstLineno (tree->right, lineno);
493 /*-----------------------------------------------------------------*/
494 /* funcOfType :- function of type with name */
495 /*-----------------------------------------------------------------*/
497 funcOfType (char *name, sym_link * type, sym_link * argType,
501 /* create the symbol */
502 sym = newSymbol (name, 0);
504 /* setup return value */
505 sym->type = newLink ();
506 DCL_TYPE (sym->type) = FUNCTION;
507 sym->type->next = copyLinkChain (type);
508 sym->etype = getSpec (sym->type);
509 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
511 /* if arguments required */
515 args = FUNC_ARGS(sym->type) = newValue ();
519 args->type = copyLinkChain (argType);
520 args->etype = getSpec (args->type);
521 SPEC_EXTR(args->etype)=1;
524 args = args->next = newValue ();
531 allocVariables (sym);
536 /*-----------------------------------------------------------------*/
537 /* funcOfTypeVarg :- function of type with name and argtype */
538 /*-----------------------------------------------------------------*/
540 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
545 /* create the symbol */
546 sym = newSymbol (name, 0);
548 /* setup return value */
549 sym->type = newLink ();
550 DCL_TYPE (sym->type) = FUNCTION;
551 sym->type->next = typeFromStr(rtype);
552 sym->etype = getSpec (sym->type);
554 /* if arguments required */
557 args = FUNC_ARGS(sym->type) = newValue ();
559 for ( i = 0 ; i < nArgs ; i++ ) {
560 args->type = typeFromStr(atypes[i]);
561 args->etype = getSpec (args->type);
562 SPEC_EXTR(args->etype)=1;
563 if ((i + 1) == nArgs) break;
564 args = args->next = newValue ();
571 allocVariables (sym);
576 /*-----------------------------------------------------------------*/
577 /* reverseParms - will reverse a parameter tree */
578 /*-----------------------------------------------------------------*/
580 reverseParms (ast * ptree)
586 /* top down if we find a nonParm tree then quit */
587 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
590 ptree->left = ptree->right;
591 ptree->right = ttree;
592 reverseParms (ptree->left);
593 reverseParms (ptree->right);
599 /*-----------------------------------------------------------------*/
600 /* processParms - makes sure the parameters are okay and do some */
601 /* processing with them */
602 /*-----------------------------------------------------------------*/
604 processParms (ast * func,
607 int *parmNumber, // unused, although updated
610 /* if none of them exist */
611 if (!defParm && !actParm)
615 if (getenv("DEBUG_SANITY")) {
616 fprintf (stderr, "processParms: %s ", defParm->name);
618 /* make sure the type is complete and sane */
619 checkTypeSanity(defParm->etype, defParm->name);
622 /* if the function is being called via a pointer & */
623 /* it has not been defined a reentrant then we cannot */
624 /* have parameters */
625 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
627 werror (W_NONRENT_ARGS);
631 /* if defined parameters ended but actual parameters */
632 /* exist and this is not defined as a variable arg */
633 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
635 werror (E_TOO_MANY_PARMS);
639 /* if defined parameters present but no actual parameters */
640 if (defParm && !actParm)
642 werror (E_TOO_FEW_PARMS);
646 if (IS_VOID(actParm->ftype)) {
647 werror (E_VOID_VALUE_USED);
651 /* If this is a varargs function... */
652 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
657 if (IS_CAST_OP (actParm)
658 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
660 /* Parameter was explicitly typecast; don't touch it. */
664 ftype = actParm->ftype;
666 /* If it's a small integer, upcast to int. */
667 if (IS_INTEGRAL (ftype)
668 && (getSize (ftype) < (unsigned) INTSIZE))
670 newType = newAst_LINK(INTTYPE);
673 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
675 newType = newAst_LINK (copyLinkChain(ftype));
676 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
679 if (IS_AGGREGATE (ftype))
681 newType = newAst_LINK (copyLinkChain (ftype));
682 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
686 /* cast required; change this op to a cast. */
687 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
689 actParm->type = EX_OP;
690 actParm->opval.op = CAST;
691 actParm->left = newType;
692 actParm->right = parmCopy;
693 decorateType (actParm);
695 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
697 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
698 processParms (func, NULL, actParm->right, parmNumber, rightmost));
703 /* if defined parameters ended but actual has not & */
705 if (!defParm && actParm &&
706 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
709 resolveSymbols (actParm);
710 /* if this is a PARAM node then match left & right */
711 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
713 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
714 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
718 /* If we have found a value node by following only right-hand links,
719 * then we know that there are no more values after us.
721 * Therefore, if there are more defined parameters, the caller didn't
724 if (rightmost && defParm->next)
726 werror (E_TOO_FEW_PARMS);
731 /* the parameter type must be at least castable */
732 if (compareType (defParm->type, actParm->ftype) == 0) {
733 werror (E_INCOMPAT_TYPES);
734 printFromToType (actParm->ftype, defParm->type);
738 /* if the parameter is castable then add the cast */
739 if (compareType (defParm->type, actParm->ftype) < 0)
741 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
743 /* now change the current one to a cast */
744 actParm->type = EX_OP;
745 actParm->opval.op = CAST;
746 actParm->left = newAst_LINK (defParm->type);
747 actParm->right = pTree;
748 actParm->etype = defParm->etype;
749 actParm->ftype = defParm->type;
750 actParm->decorated=0; /* force typechecking */
751 decorateType (actParm);
754 /* make a copy and change the regparm type to the defined parm */
755 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
756 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
757 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
761 /*-----------------------------------------------------------------*/
762 /* createIvalType - generates ival for basic types */
763 /*-----------------------------------------------------------------*/
765 createIvalType (ast * sym, sym_link * type, initList * ilist)
769 /* if initList is deep */
770 if (ilist->type == INIT_DEEP)
771 ilist = ilist->init.deep;
773 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
774 return decorateType (newNode ('=', sym, iExpr));
777 /*-----------------------------------------------------------------*/
778 /* createIvalStruct - generates initial value for structures */
779 /*-----------------------------------------------------------------*/
781 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
788 sflds = SPEC_STRUCT (type)->fields;
789 if (ilist->type != INIT_DEEP)
791 werror (E_INIT_STRUCT, "");
795 iloop = ilist->init.deep;
797 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
799 /* if we have come to end */
803 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
804 lAst = decorateType (resolveSymbols (lAst));
805 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
809 werror (W_EXCESS_INITIALIZERS, "struct",
810 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
817 /*-----------------------------------------------------------------*/
818 /* createIvalArray - generates code for array initialization */
819 /*-----------------------------------------------------------------*/
821 createIvalArray (ast * sym, sym_link * type, initList * ilist)
825 int lcnt = 0, size = 0;
826 literalList *literalL;
828 /* take care of the special case */
829 /* array of characters can be init */
831 if (IS_CHAR (type->next))
832 if ((rast = createIvalCharPtr (sym,
834 decorateType (resolveSymbols (list2expr (ilist))))))
836 return decorateType (resolveSymbols (rast));
838 /* not the special case */
839 if (ilist->type != INIT_DEEP)
841 werror (E_INIT_STRUCT, "");
845 iloop = ilist->init.deep;
846 lcnt = DCL_ELEM (type);
848 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
852 aSym = decorateType (resolveSymbols(sym));
854 rast = newNode(ARRAYINIT, aSym, NULL);
855 rast->values.constlist = literalL;
857 // Make sure size is set to length of initializer list.
864 if (lcnt && size > lcnt)
866 // Array size was specified, and we have more initializers than needed.
867 char *name=sym->opval.val->sym->name;
868 int lineno=sym->opval.val->sym->lineDef;
870 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
879 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
880 aSym = decorateType (resolveSymbols (aSym));
881 rast = createIval (aSym, type->next, iloop, rast);
882 iloop = (iloop ? iloop->next : NULL);
888 /* no of elements given and we */
889 /* have generated for all of them */
892 // there has to be a better way
893 char *name=sym->opval.val->sym->name;
894 int lineno=sym->opval.val->sym->lineDef;
895 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
902 /* if we have not been given a size */
903 if (!DCL_ELEM (type))
905 DCL_ELEM (type) = size;
908 return decorateType (resolveSymbols (rast));
912 /*-----------------------------------------------------------------*/
913 /* createIvalCharPtr - generates initial values for char pointers */
914 /*-----------------------------------------------------------------*/
916 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
920 /* if this is a pointer & right is a literal array then */
921 /* just assignment will do */
922 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
923 SPEC_SCLS (iexpr->etype) == S_CODE)
924 && IS_ARRAY (iexpr->ftype)))
925 return newNode ('=', sym, iexpr);
927 /* left side is an array so we have to assign each */
929 if ((IS_LITERAL (iexpr->etype) ||
930 SPEC_SCLS (iexpr->etype) == S_CODE)
931 && IS_ARRAY (iexpr->ftype))
933 /* for each character generate an assignment */
934 /* to the array element */
935 char *s = SPEC_CVAL (iexpr->etype).v_char;
940 rast = newNode (NULLOP,
944 newAst_VALUE (valueFromLit ((float) i))),
945 newAst_VALUE (valueFromLit (*s))));
949 rast = newNode (NULLOP,
953 newAst_VALUE (valueFromLit ((float) i))),
954 newAst_VALUE (valueFromLit (*s))));
956 // now we don't need iexpr's symbol anymore
958 symbol *sym=AST_SYMBOL(iexpr);
959 memmap *segment=SPEC_OCLS(sym->etype);
960 deleteSetItem(&segment->syms, sym);
962 return decorateType (resolveSymbols (rast));
968 /*-----------------------------------------------------------------*/
969 /* createIvalPtr - generates initial value for pointers */
970 /*-----------------------------------------------------------------*/
972 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
978 if (ilist->type == INIT_DEEP)
979 ilist = ilist->init.deep;
981 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
983 /* if character pointer */
984 if (IS_CHAR (type->next))
985 if ((rast = createIvalCharPtr (sym, type, iexpr)))
988 return newNode ('=', sym, iexpr);
991 /*-----------------------------------------------------------------*/
992 /* createIval - generates code for initial value */
993 /*-----------------------------------------------------------------*/
995 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1002 /* if structure then */
1003 if (IS_STRUCT (type))
1004 rast = createIvalStruct (sym, type, ilist);
1006 /* if this is a pointer */
1008 rast = createIvalPtr (sym, type, ilist);
1010 /* if this is an array */
1011 if (IS_ARRAY (type))
1012 rast = createIvalArray (sym, type, ilist);
1014 /* if type is SPECIFIER */
1016 rast = createIvalType (sym, type, ilist);
1019 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1021 return decorateType (resolveSymbols (rast));
1024 /*-----------------------------------------------------------------*/
1025 /* initAggregates - initialises aggregate variables with initv */
1026 /*-----------------------------------------------------------------*/
1027 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1028 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1031 /*-----------------------------------------------------------------*/
1032 /* gatherAutoInit - creates assignment expressions for initial */
1034 /*-----------------------------------------------------------------*/
1036 gatherAutoInit (symbol * autoChain)
1043 for (sym = autoChain; sym; sym = sym->next)
1046 /* resolve the symbols in the ival */
1048 resolveIvalSym (sym->ival);
1050 /* if this is a static variable & has an */
1051 /* initial value the code needs to be lifted */
1052 /* here to the main portion since they can be */
1053 /* initialised only once at the start */
1054 if (IS_STATIC (sym->etype) && sym->ival &&
1055 SPEC_SCLS (sym->etype) != S_CODE)
1059 /* insert the symbol into the symbol table */
1060 /* with level = 0 & name = rname */
1061 newSym = copySymbol (sym);
1062 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1064 /* now lift the code to main */
1065 if (IS_AGGREGATE (sym->type)) {
1066 work = initAggregates (sym, sym->ival, NULL);
1068 if (getNelements(sym->type, sym->ival)>1) {
1069 werror (W_EXCESS_INITIALIZERS, "scalar",
1070 sym->name, sym->lineDef);
1072 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1073 list2expr (sym->ival));
1076 setAstLineno (work, sym->lineDef);
1080 staticAutos = newNode (NULLOP, staticAutos, work);
1087 /* if there is an initial value */
1088 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1090 initList *ilist=sym->ival;
1092 while (ilist->type == INIT_DEEP) {
1093 ilist = ilist->init.deep;
1096 /* update lineno for error msg */
1097 lineno=sym->lineDef;
1098 setAstLineno (ilist->init.node, lineno);
1100 if (IS_AGGREGATE (sym->type)) {
1101 work = initAggregates (sym, sym->ival, NULL);
1103 if (getNelements(sym->type, sym->ival)>1) {
1104 werror (W_EXCESS_INITIALIZERS, "scalar",
1105 sym->name, sym->lineDef);
1107 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1108 list2expr (sym->ival));
1112 setAstLineno (work, sym->lineDef);
1116 init = newNode (NULLOP, init, work);
1125 /*-----------------------------------------------------------------*/
1126 /* stringToSymbol - creates a symbol from a literal string */
1127 /*-----------------------------------------------------------------*/
1129 stringToSymbol (value * val)
1131 char name[SDCC_NAME_MAX + 1];
1132 static int charLbl = 0;
1135 sprintf (name, "_str_%d", charLbl++);
1136 sym = newSymbol (name, 0); /* make it @ level 0 */
1137 strcpy (sym->rname, name);
1139 /* copy the type from the value passed */
1140 sym->type = copyLinkChain (val->type);
1141 sym->etype = getSpec (sym->type);
1142 /* change to storage class & output class */
1143 SPEC_SCLS (sym->etype) = S_CODE;
1144 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1145 SPEC_STAT (sym->etype) = 1;
1146 /* make the level & block = 0 */
1147 sym->block = sym->level = 0;
1149 /* create an ival */
1150 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1155 allocVariables (sym);
1158 return symbolVal (sym);
1162 /*-----------------------------------------------------------------*/
1163 /* processBlockVars - will go thru the ast looking for block if */
1164 /* a block is found then will allocate the syms */
1165 /* will also gather the auto inits present */
1166 /*-----------------------------------------------------------------*/
1168 processBlockVars (ast * tree, int *stack, int action)
1173 /* if this is a block */
1174 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1178 if (action == ALLOCATE)
1180 *stack += allocVariables (tree->values.sym);
1181 autoInit = gatherAutoInit (tree->values.sym);
1183 /* if there are auto inits then do them */
1185 tree->left = newNode (NULLOP, autoInit, tree->left);
1187 else /* action is deallocate */
1188 deallocLocal (tree->values.sym);
1191 processBlockVars (tree->left, stack, action);
1192 processBlockVars (tree->right, stack, action);
1196 /*-------------------------------------------------------------*/
1197 /* constExprTree - returns TRUE if this tree is a constant */
1199 /*-------------------------------------------------------------*/
1200 bool constExprTree (ast *cexpr) {
1206 cexpr = decorateType (resolveSymbols (cexpr));
1208 switch (cexpr->type)
1211 if (IS_AST_LIT_VALUE(cexpr)) {
1212 // this is a literal
1215 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1216 // a function's address will never change
1219 if (IS_AST_SYM_VALUE(cexpr) &&
1220 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1221 // a symbol in code space will never change
1222 // This is only for the 'char *s="hallo"' case and will have to leave
1227 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1228 "unexpected link in expression tree\n");
1231 if (cexpr->opval.op==ARRAYINIT) {
1232 // this is a list of literals
1235 if (cexpr->opval.op=='=') {
1236 return constExprTree(cexpr->right);
1238 if (cexpr->opval.op==CAST) {
1239 // jwk: cast ignored, maybe we should throw a warning here
1240 return constExprTree(cexpr->right);
1242 if (cexpr->opval.op=='&') {
1245 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1248 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1255 /*-----------------------------------------------------------------*/
1256 /* constExprValue - returns the value of a constant expression */
1257 /* or NULL if it is not a constant expression */
1258 /*-----------------------------------------------------------------*/
1260 constExprValue (ast * cexpr, int check)
1262 cexpr = decorateType (resolveSymbols (cexpr));
1264 /* if this is not a constant then */
1265 if (!IS_LITERAL (cexpr->ftype))
1267 /* then check if this is a literal array
1269 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1270 SPEC_CVAL (cexpr->etype).v_char &&
1271 IS_ARRAY (cexpr->ftype))
1273 value *val = valFromType (cexpr->ftype);
1274 SPEC_SCLS (val->etype) = S_LITERAL;
1275 val->sym = cexpr->opval.val->sym;
1276 val->sym->type = copyLinkChain (cexpr->ftype);
1277 val->sym->etype = getSpec (val->sym->type);
1278 strcpy (val->name, cexpr->opval.val->sym->rname);
1282 /* if we are casting a literal value then */
1283 if (IS_AST_OP (cexpr) &&
1284 cexpr->opval.op == CAST &&
1285 IS_LITERAL (cexpr->right->ftype))
1286 return valCastLiteral (cexpr->ftype,
1287 floatFromVal (cexpr->right->opval.val));
1289 if (IS_AST_VALUE (cexpr))
1290 return cexpr->opval.val;
1293 werror (E_CONST_EXPECTED, "found expression");
1298 /* return the value */
1299 return cexpr->opval.val;
1303 /*-----------------------------------------------------------------*/
1304 /* isLabelInAst - will return true if a given label is found */
1305 /*-----------------------------------------------------------------*/
1307 isLabelInAst (symbol * label, ast * tree)
1309 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1312 if (IS_AST_OP (tree) &&
1313 tree->opval.op == LABEL &&
1314 isSymbolEqual (AST_SYMBOL (tree->left), label))
1317 return isLabelInAst (label, tree->right) &&
1318 isLabelInAst (label, tree->left);
1322 /*-----------------------------------------------------------------*/
1323 /* isLoopCountable - return true if the loop count can be determi- */
1324 /* -ned at compile time . */
1325 /*-----------------------------------------------------------------*/
1327 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1328 symbol ** sym, ast ** init, ast ** end)
1331 /* the loop is considered countable if the following
1332 conditions are true :-
1334 a) initExpr :- <sym> = <const>
1335 b) condExpr :- <sym> < <const1>
1336 c) loopExpr :- <sym> ++
1339 /* first check the initExpr */
1340 if (IS_AST_OP (initExpr) &&
1341 initExpr->opval.op == '=' && /* is assignment */
1342 IS_AST_SYM_VALUE (initExpr->left))
1343 { /* left is a symbol */
1345 *sym = AST_SYMBOL (initExpr->left);
1346 *init = initExpr->right;
1351 /* for now the symbol has to be of
1353 if (!IS_INTEGRAL ((*sym)->type))
1356 /* now check condExpr */
1357 if (IS_AST_OP (condExpr))
1360 switch (condExpr->opval.op)
1363 if (IS_AST_SYM_VALUE (condExpr->left) &&
1364 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1365 IS_AST_LIT_VALUE (condExpr->right))
1367 *end = condExpr->right;
1373 if (IS_AST_OP (condExpr->left) &&
1374 condExpr->left->opval.op == '>' &&
1375 IS_AST_LIT_VALUE (condExpr->left->right) &&
1376 IS_AST_SYM_VALUE (condExpr->left->left) &&
1377 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1380 *end = newNode ('+', condExpr->left->right,
1381 newAst_VALUE (constVal ("1")));
1392 /* check loop expression is of the form <sym>++ */
1393 if (!IS_AST_OP (loopExpr))
1396 /* check if <sym> ++ */
1397 if (loopExpr->opval.op == INC_OP)
1403 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1404 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1411 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1412 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1420 if (loopExpr->opval.op == ADD_ASSIGN)
1423 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1424 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1425 IS_AST_LIT_VALUE (loopExpr->right) &&
1426 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1434 /*-----------------------------------------------------------------*/
1435 /* astHasVolatile - returns true if ast contains any volatile */
1436 /*-----------------------------------------------------------------*/
1438 astHasVolatile (ast * tree)
1443 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1446 if (IS_AST_OP (tree))
1447 return astHasVolatile (tree->left) ||
1448 astHasVolatile (tree->right);
1453 /*-----------------------------------------------------------------*/
1454 /* astHasPointer - return true if the ast contains any ptr variable */
1455 /*-----------------------------------------------------------------*/
1457 astHasPointer (ast * tree)
1462 if (IS_AST_LINK (tree))
1465 /* if we hit an array expression then check
1466 only the left side */
1467 if (IS_AST_OP (tree) && tree->opval.op == '[')
1468 return astHasPointer (tree->left);
1470 if (IS_AST_VALUE (tree))
1471 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1473 return astHasPointer (tree->left) ||
1474 astHasPointer (tree->right);
1478 /*-----------------------------------------------------------------*/
1479 /* astHasSymbol - return true if the ast has the given symbol */
1480 /*-----------------------------------------------------------------*/
1482 astHasSymbol (ast * tree, symbol * sym)
1484 if (!tree || IS_AST_LINK (tree))
1487 if (IS_AST_VALUE (tree))
1489 if (IS_AST_SYM_VALUE (tree))
1490 return isSymbolEqual (AST_SYMBOL (tree), sym);
1495 return astHasSymbol (tree->left, sym) ||
1496 astHasSymbol (tree->right, sym);
1499 /*-----------------------------------------------------------------*/
1500 /* astHasDeref - return true if the ast has an indirect access */
1501 /*-----------------------------------------------------------------*/
1503 astHasDeref (ast * tree)
1505 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1508 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1510 return astHasDeref (tree->left) || astHasDeref (tree->right);
1513 /*-----------------------------------------------------------------*/
1514 /* isConformingBody - the loop body has to conform to a set of rules */
1515 /* for the loop to be considered reversible read on for rules */
1516 /*-----------------------------------------------------------------*/
1518 isConformingBody (ast * pbody, symbol * sym, ast * body)
1521 /* we are going to do a pre-order traversal of the
1522 tree && check for the following conditions. (essentially
1523 a set of very shallow tests )
1524 a) the sym passed does not participate in
1525 any arithmetic operation
1526 b) There are no function calls
1527 c) all jumps are within the body
1528 d) address of loop control variable not taken
1529 e) if an assignment has a pointer on the
1530 left hand side make sure right does not have
1531 loop control variable */
1533 /* if we reach the end or a leaf then true */
1534 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1537 /* if anything else is "volatile" */
1538 if (IS_VOLATILE (TETYPE (pbody)))
1541 /* we will walk the body in a pre-order traversal for
1543 switch (pbody->opval.op)
1545 /*------------------------------------------------------------------*/
1547 // if the loopvar is used as an index
1548 if (astHasSymbol(pbody->right, sym)) {
1551 return isConformingBody (pbody->right, sym, body);
1553 /*------------------------------------------------------------------*/
1558 /*------------------------------------------------------------------*/
1559 case INC_OP: /* incerement operator unary so left only */
1562 /* sure we are not sym is not modified */
1564 IS_AST_SYM_VALUE (pbody->left) &&
1565 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1569 IS_AST_SYM_VALUE (pbody->right) &&
1570 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1575 /*------------------------------------------------------------------*/
1577 case '*': /* can be unary : if right is null then unary operation */
1582 /* if right is NULL then unary operation */
1583 /*------------------------------------------------------------------*/
1584 /*----------------------------*/
1586 /*----------------------------*/
1589 if (IS_AST_SYM_VALUE (pbody->left) &&
1590 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1593 return isConformingBody (pbody->left, sym, body);
1597 if (astHasSymbol (pbody->left, sym) ||
1598 astHasSymbol (pbody->right, sym))
1603 /*------------------------------------------------------------------*/
1611 if (IS_AST_SYM_VALUE (pbody->left) &&
1612 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1615 if (IS_AST_SYM_VALUE (pbody->right) &&
1616 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1619 return isConformingBody (pbody->left, sym, body) &&
1620 isConformingBody (pbody->right, sym, body);
1627 if (IS_AST_SYM_VALUE (pbody->left) &&
1628 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1630 return isConformingBody (pbody->left, sym, body);
1632 /*------------------------------------------------------------------*/
1644 case SIZEOF: /* evaluate wihout code generation */
1646 return isConformingBody (pbody->left, sym, body) &&
1647 isConformingBody (pbody->right, sym, body);
1649 /*------------------------------------------------------------------*/
1652 /* if left has a pointer & right has loop
1653 control variable then we cannot */
1654 if (astHasPointer (pbody->left) &&
1655 astHasSymbol (pbody->right, sym))
1657 if (astHasVolatile (pbody->left))
1660 if (IS_AST_SYM_VALUE (pbody->left)) {
1661 // if the loopvar has an assignment
1662 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1664 // if the loopvar is used in another (maybe conditional) block
1665 if (astHasSymbol (pbody->right, sym) &&
1666 (pbody->level > body->level)) {
1671 if (astHasVolatile (pbody->left))
1674 if (astHasDeref(pbody->right)) return FALSE;
1676 return isConformingBody (pbody->left, sym, body) &&
1677 isConformingBody (pbody->right, sym, body);
1688 assert ("Parser should not have generated this\n");
1690 /*------------------------------------------------------------------*/
1691 /*----------------------------*/
1692 /* comma operator */
1693 /*----------------------------*/
1695 return isConformingBody (pbody->left, sym, body) &&
1696 isConformingBody (pbody->right, sym, body);
1698 /*------------------------------------------------------------------*/
1699 /*----------------------------*/
1701 /*----------------------------*/
1703 /* if local & not passed as paramater then ok */
1704 if (sym->level && !astHasSymbol(pbody->right,sym))
1708 /*------------------------------------------------------------------*/
1709 /*----------------------------*/
1710 /* return statement */
1711 /*----------------------------*/
1716 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1721 if (astHasSymbol (pbody->left, sym))
1728 return isConformingBody (pbody->left, sym, body) &&
1729 isConformingBody (pbody->right, sym, body);
1735 /*-----------------------------------------------------------------*/
1736 /* isLoopReversible - takes a for loop as input && returns true */
1737 /* if the for loop is reversible. If yes will set the value of */
1738 /* the loop control var & init value & termination value */
1739 /*-----------------------------------------------------------------*/
1741 isLoopReversible (ast * loop, symbol ** loopCntrl,
1742 ast ** init, ast ** end)
1744 /* if option says don't do it then don't */
1745 if (optimize.noLoopReverse)
1747 /* there are several tests to determine this */
1749 /* for loop has to be of the form
1750 for ( <sym> = <const1> ;
1751 [<sym> < <const2>] ;
1752 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1754 if (!isLoopCountable (AST_FOR (loop, initExpr),
1755 AST_FOR (loop, condExpr),
1756 AST_FOR (loop, loopExpr),
1757 loopCntrl, init, end))
1760 /* now do some serious checking on the body of the loop
1763 return isConformingBody (loop->left, *loopCntrl, loop->left);
1767 /*-----------------------------------------------------------------*/
1768 /* replLoopSym - replace the loop sym by loop sym -1 */
1769 /*-----------------------------------------------------------------*/
1771 replLoopSym (ast * body, symbol * sym)
1774 if (!body || IS_AST_LINK (body))
1777 if (IS_AST_SYM_VALUE (body))
1780 if (isSymbolEqual (AST_SYMBOL (body), sym))
1784 body->opval.op = '-';
1785 body->left = newAst_VALUE (symbolVal (sym));
1786 body->right = newAst_VALUE (constVal ("1"));
1794 replLoopSym (body->left, sym);
1795 replLoopSym (body->right, sym);
1799 /*-----------------------------------------------------------------*/
1800 /* reverseLoop - do the actual loop reversal */
1801 /*-----------------------------------------------------------------*/
1803 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1807 /* create the following tree
1812 if (sym) goto for_continue ;
1815 /* put it together piece by piece */
1816 rloop = newNode (NULLOP,
1817 createIf (newAst_VALUE (symbolVal (sym)),
1819 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1822 newAst_VALUE (symbolVal (sym)),
1825 replLoopSym (loop->left, sym);
1826 setAstLineno (rloop, init->lineno);
1828 rloop = newNode (NULLOP,
1830 newAst_VALUE (symbolVal (sym)),
1831 newNode ('-', end, init)),
1832 createLabel (AST_FOR (loop, continueLabel),
1836 newNode (SUB_ASSIGN,
1837 newAst_VALUE (symbolVal (sym)),
1838 newAst_VALUE (constVal ("1"))),
1841 rloop->lineno=init->lineno;
1842 return decorateType (rloop);
1846 /*-----------------------------------------------------------------*/
1847 /* decorateType - compute type for this tree also does type cheking */
1848 /* this is done bottom up, since type have to flow upwards */
1849 /* it also does constant folding, and paramater checking */
1850 /*-----------------------------------------------------------------*/
1852 decorateType (ast * tree)
1860 /* if already has type then do nothing */
1861 if (tree->decorated)
1864 tree->decorated = 1;
1867 /* print the line */
1868 /* if not block & function */
1869 if (tree->type == EX_OP &&
1870 (tree->opval.op != FUNCTION &&
1871 tree->opval.op != BLOCK &&
1872 tree->opval.op != NULLOP))
1874 filename = tree->filename;
1875 lineno = tree->lineno;
1879 /* if any child is an error | this one is an error do nothing */
1880 if (tree->isError ||
1881 (tree->left && tree->left->isError) ||
1882 (tree->right && tree->right->isError))
1885 /*------------------------------------------------------------------*/
1886 /*----------------------------*/
1887 /* leaf has been reached */
1888 /*----------------------------*/
1889 /* if this is of type value */
1890 /* just get the type */
1891 if (tree->type == EX_VALUE)
1894 if (IS_LITERAL (tree->opval.val->etype))
1897 /* if this is a character array then declare it */
1898 if (IS_ARRAY (tree->opval.val->type))
1899 tree->opval.val = stringToSymbol (tree->opval.val);
1901 /* otherwise just copy the type information */
1902 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1906 if (tree->opval.val->sym)
1908 /* if the undefined flag is set then give error message */
1909 if (tree->opval.val->sym->undefined)
1911 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1913 TTYPE (tree) = TETYPE (tree) =
1914 tree->opval.val->type = tree->opval.val->sym->type =
1915 tree->opval.val->etype = tree->opval.val->sym->etype =
1916 copyLinkChain (INTTYPE);
1921 /* if impilicit i.e. struct/union member then no type */
1922 if (tree->opval.val->sym->implicit)
1923 TTYPE (tree) = TETYPE (tree) = NULL;
1928 /* else copy the type */
1929 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1931 /* and mark it as referenced */
1932 tree->opval.val->sym->isref = 1;
1940 /* if type link for the case of cast */
1941 if (tree->type == EX_LINK)
1943 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1950 dtl = decorateType (tree->left);
1951 /* delay right side for '?' operator since conditional macro expansions might
1953 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1955 /* this is to take care of situations
1956 when the tree gets rewritten */
1957 if (dtl != tree->left)
1959 if (dtr != tree->right)
1962 /* special case for some operations: cast up right->left if type of left
1963 has greater size than right */
1964 if (tree->left && tree->right && IS_AST_OP(tree->right) &&
1965 (tree->right->opval.op == LEFT_OP ||
1966 (tree->right->opval.op == '*' /* for int -> long only */ &&
1967 tree->right->right /* but not for deref */ ) ||
1968 tree->right->opval.op == '+' ||
1969 tree->right->opval.op == '-')) {
1970 int lsize = getSize(LTYPE(tree));
1971 int rsize = getSize(RTYPE(tree));
1973 if (lsize > rsize) {
1974 tree->right->decorated = 0;
1975 tree->right->left = newNode( CAST, (lsize == 2 ?
1976 newAst_LINK(newIntLink()) :
1977 newAst_LINK(newLongLink())),
1979 tree->right = decorateType(tree->right);
1984 /* depending on type of operator do */
1986 switch (tree->opval.op)
1988 /*------------------------------------------------------------------*/
1989 /*----------------------------*/
1991 /*----------------------------*/
1994 /* determine which is the array & which the index */
1995 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1998 ast *tempTree = tree->left;
1999 tree->left = tree->right;
2000 tree->right = tempTree;
2003 /* first check if this is a array or a pointer */
2004 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2006 werror (E_NEED_ARRAY_PTR, "[]");
2007 goto errorTreeReturn;
2010 /* check if the type of the idx */
2011 if (!IS_INTEGRAL (RTYPE (tree)))
2013 werror (E_IDX_NOT_INT);
2014 goto errorTreeReturn;
2017 /* if the left is an rvalue then error */
2020 werror (E_LVALUE_REQUIRED, "array access");
2021 goto errorTreeReturn;
2024 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2025 if (IS_PTR(LTYPE(tree))) {
2026 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2030 /*------------------------------------------------------------------*/
2031 /*----------------------------*/
2033 /*----------------------------*/
2035 /* if this is not a structure */
2036 if (!IS_STRUCT (LTYPE (tree)))
2038 werror (E_STRUCT_UNION, ".");
2039 goto errorTreeReturn;
2041 TTYPE (tree) = structElemType (LTYPE (tree),
2042 (tree->right->type == EX_VALUE ?
2043 tree->right->opval.val : NULL));
2044 TETYPE (tree) = getSpec (TTYPE (tree));
2047 /*------------------------------------------------------------------*/
2048 /*----------------------------*/
2049 /* struct/union pointer */
2050 /*----------------------------*/
2052 /* if not pointer to a structure */
2053 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2055 werror (E_PTR_REQD);
2056 goto errorTreeReturn;
2059 if (!IS_STRUCT (LTYPE (tree)->next))
2061 werror (E_STRUCT_UNION, "->");
2062 goto errorTreeReturn;
2065 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2066 (tree->right->type == EX_VALUE ?
2067 tree->right->opval.val : NULL));
2068 TETYPE (tree) = getSpec (TTYPE (tree));
2070 /* adjust the storage class */
2071 switch (DCL_TYPE(tree->left->ftype)) {
2075 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2078 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2083 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2086 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2089 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2099 /*------------------------------------------------------------------*/
2100 /*----------------------------*/
2101 /* ++/-- operation */
2102 /*----------------------------*/
2103 case INC_OP: /* incerement operator unary so left only */
2106 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2107 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2108 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2109 werror (E_CODE_WRITE, "++/--");
2118 /*------------------------------------------------------------------*/
2119 /*----------------------------*/
2121 /*----------------------------*/
2122 case '&': /* can be unary */
2123 /* if right is NULL then unary operation */
2124 if (tree->right) /* not an unary operation */
2127 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2129 werror (E_BITWISE_OP);
2130 werror (W_CONTINUE, "left & right types are ");
2131 printTypeChain (LTYPE (tree), stderr);
2132 fprintf (stderr, ",");
2133 printTypeChain (RTYPE (tree), stderr);
2134 fprintf (stderr, "\n");
2135 goto errorTreeReturn;
2138 /* if they are both literal */
2139 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2141 tree->type = EX_VALUE;
2142 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2143 valFromType (RETYPE (tree)), '&');
2145 tree->right = tree->left = NULL;
2146 TETYPE (tree) = tree->opval.val->etype;
2147 TTYPE (tree) = tree->opval.val->type;
2151 /* see if this is a GETHBIT operation if yes
2154 ast *otree = optimizeGetHbit (tree);
2157 return decorateType (otree);
2161 computeType (LTYPE (tree), RTYPE (tree));
2162 TETYPE (tree) = getSpec (TTYPE (tree));
2164 LRVAL (tree) = RRVAL (tree) = 1;
2168 /*------------------------------------------------------------------*/
2169 /*----------------------------*/
2171 /*----------------------------*/
2173 p->class = DECLARATOR;
2174 /* if bit field then error */
2175 if (IS_BITVAR (tree->left->etype))
2177 werror (E_ILLEGAL_ADDR, "address of bit variable");
2178 goto errorTreeReturn;
2181 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2183 werror (E_ILLEGAL_ADDR, "address of register variable");
2184 goto errorTreeReturn;
2187 if (IS_FUNC (LTYPE (tree)))
2189 // this ought to be ignored
2190 return (tree->left);
2193 if (IS_LITERAL(LTYPE(tree)))
2195 werror (E_ILLEGAL_ADDR, "address of literal");
2196 goto errorTreeReturn;
2201 werror (E_LVALUE_REQUIRED, "address of");
2202 goto errorTreeReturn;
2204 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2206 DCL_TYPE (p) = CPOINTER;
2207 DCL_PTR_CONST (p) = port->mem.code_ro;
2209 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2210 DCL_TYPE (p) = FPOINTER;
2211 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2212 DCL_TYPE (p) = PPOINTER;
2213 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2214 DCL_TYPE (p) = IPOINTER;
2215 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2216 DCL_TYPE (p) = EEPPOINTER;
2217 else if (SPEC_OCLS(tree->left->etype))
2218 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2220 DCL_TYPE (p) = POINTER;
2222 if (IS_AST_SYM_VALUE (tree->left))
2224 AST_SYMBOL (tree->left)->addrtaken = 1;
2225 AST_SYMBOL (tree->left)->allocreq = 1;
2228 p->next = LTYPE (tree);
2230 TETYPE (tree) = getSpec (TTYPE (tree));
2231 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2232 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2237 /*------------------------------------------------------------------*/
2238 /*----------------------------*/
2240 /*----------------------------*/
2242 /* if the rewrite succeeds then don't go any furthur */
2244 ast *wtree = optimizeRRCRLC (tree);
2246 return decorateType (wtree);
2248 /*------------------------------------------------------------------*/
2249 /*----------------------------*/
2251 /*----------------------------*/
2253 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2255 werror (E_BITWISE_OP);
2256 werror (W_CONTINUE, "left & right types are ");
2257 printTypeChain (LTYPE (tree), stderr);
2258 fprintf (stderr, ",");
2259 printTypeChain (RTYPE (tree), stderr);
2260 fprintf (stderr, "\n");
2261 goto errorTreeReturn;
2264 /* if they are both literal then */
2265 /* rewrite the tree */
2266 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2268 tree->type = EX_VALUE;
2269 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2270 valFromType (RETYPE (tree)),
2272 tree->right = tree->left = NULL;
2273 TETYPE (tree) = tree->opval.val->etype;
2274 TTYPE (tree) = tree->opval.val->type;
2277 LRVAL (tree) = RRVAL (tree) = 1;
2278 TETYPE (tree) = getSpec (TTYPE (tree) =
2279 computeType (LTYPE (tree),
2282 /*------------------------------------------------------------------*/
2283 /*----------------------------*/
2285 /*----------------------------*/
2287 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2289 werror (E_INVALID_OP, "divide");
2290 goto errorTreeReturn;
2292 /* if they are both literal then */
2293 /* rewrite the tree */
2294 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2296 tree->type = EX_VALUE;
2297 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2298 valFromType (RETYPE (tree)));
2299 tree->right = tree->left = NULL;
2300 TETYPE (tree) = getSpec (TTYPE (tree) =
2301 tree->opval.val->type);
2304 LRVAL (tree) = RRVAL (tree) = 1;
2305 TETYPE (tree) = getSpec (TTYPE (tree) =
2306 computeType (LTYPE (tree),
2310 /*------------------------------------------------------------------*/
2311 /*----------------------------*/
2313 /*----------------------------*/
2315 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2317 werror (E_BITWISE_OP);
2318 werror (W_CONTINUE, "left & right types are ");
2319 printTypeChain (LTYPE (tree), stderr);
2320 fprintf (stderr, ",");
2321 printTypeChain (RTYPE (tree), stderr);
2322 fprintf (stderr, "\n");
2323 goto errorTreeReturn;
2325 /* if they are both literal then */
2326 /* rewrite the tree */
2327 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2329 tree->type = EX_VALUE;
2330 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2331 valFromType (RETYPE (tree)));
2332 tree->right = tree->left = NULL;
2333 TETYPE (tree) = getSpec (TTYPE (tree) =
2334 tree->opval.val->type);
2337 LRVAL (tree) = RRVAL (tree) = 1;
2338 TETYPE (tree) = getSpec (TTYPE (tree) =
2339 computeType (LTYPE (tree),
2343 /*------------------------------------------------------------------*/
2344 /*----------------------------*/
2345 /* address dereference */
2346 /*----------------------------*/
2347 case '*': /* can be unary : if right is null then unary operation */
2350 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2352 werror (E_PTR_REQD);
2353 goto errorTreeReturn;
2358 werror (E_LVALUE_REQUIRED, "pointer deref");
2359 goto errorTreeReturn;
2361 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2362 LTYPE (tree)->next : NULL);
2363 TETYPE (tree) = getSpec (TTYPE (tree));
2364 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2368 /*------------------------------------------------------------------*/
2369 /*----------------------------*/
2370 /* multiplication */
2371 /*----------------------------*/
2372 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2374 werror (E_INVALID_OP, "multiplication");
2375 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 = valMult (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 left is a literal exchange left & right */
2392 if (IS_LITERAL (LTYPE (tree)))
2394 ast *tTree = tree->left;
2395 tree->left = tree->right;
2396 tree->right = tTree;
2399 LRVAL (tree) = RRVAL (tree) = 1;
2400 TETYPE (tree) = getSpec (TTYPE (tree) =
2401 computeType (LTYPE (tree),
2403 /* promote result to int if left & right are char
2404 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2405 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2406 SPEC_NOUN(TETYPE(tree)) = V_INT;
2410 /*------------------------------------------------------------------*/
2411 /*----------------------------*/
2412 /* unary '+' operator */
2413 /*----------------------------*/
2418 if (!IS_INTEGRAL (LTYPE (tree)))
2420 werror (E_UNARY_OP, '+');
2421 goto errorTreeReturn;
2424 /* if left is a literal then do it */
2425 if (IS_LITERAL (LTYPE (tree)))
2427 tree->type = EX_VALUE;
2428 tree->opval.val = valFromType (LETYPE (tree));
2430 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2434 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2438 /*------------------------------------------------------------------*/
2439 /*----------------------------*/
2441 /*----------------------------*/
2443 /* this is not a unary operation */
2444 /* if both pointers then problem */
2445 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2446 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2448 werror (E_PTR_PLUS_PTR);
2449 goto errorTreeReturn;
2452 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2453 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2455 werror (E_PLUS_INVALID, "+");
2456 goto errorTreeReturn;
2459 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2460 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2462 werror (E_PLUS_INVALID, "+");
2463 goto errorTreeReturn;
2465 /* if they are both literal then */
2466 /* rewrite the tree */
2467 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2469 tree->type = EX_VALUE;
2470 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2471 valFromType (RETYPE (tree)));
2472 tree->right = tree->left = NULL;
2473 TETYPE (tree) = getSpec (TTYPE (tree) =
2474 tree->opval.val->type);
2478 /* if the right is a pointer or left is a literal
2479 xchange left & right */
2480 if (IS_ARRAY (RTYPE (tree)) ||
2481 IS_PTR (RTYPE (tree)) ||
2482 IS_LITERAL (LTYPE (tree)))
2484 ast *tTree = tree->left;
2485 tree->left = tree->right;
2486 tree->right = tTree;
2489 LRVAL (tree) = RRVAL (tree) = 1;
2490 /* if the left is a pointer */
2491 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2492 TETYPE (tree) = getSpec (TTYPE (tree) =
2495 TETYPE (tree) = getSpec (TTYPE (tree) =
2496 computeType (LTYPE (tree),
2500 /*------------------------------------------------------------------*/
2501 /*----------------------------*/
2503 /*----------------------------*/
2504 case '-': /* can be unary */
2505 /* if right is null then unary */
2509 if (!IS_ARITHMETIC (LTYPE (tree)))
2511 werror (E_UNARY_OP, tree->opval.op);
2512 goto errorTreeReturn;
2515 /* if left is a literal then do it */
2516 if (IS_LITERAL (LTYPE (tree)))
2518 tree->type = EX_VALUE;
2519 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2521 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2522 SPEC_USIGN(TETYPE(tree)) = 0;
2526 TTYPE (tree) = LTYPE (tree);
2530 /*------------------------------------------------------------------*/
2531 /*----------------------------*/
2533 /*----------------------------*/
2535 if (!(IS_PTR (LTYPE (tree)) ||
2536 IS_ARRAY (LTYPE (tree)) ||
2537 IS_ARITHMETIC (LTYPE (tree))))
2539 werror (E_PLUS_INVALID, "-");
2540 goto errorTreeReturn;
2543 if (!(IS_PTR (RTYPE (tree)) ||
2544 IS_ARRAY (RTYPE (tree)) ||
2545 IS_ARITHMETIC (RTYPE (tree))))
2547 werror (E_PLUS_INVALID, "-");
2548 goto errorTreeReturn;
2551 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2552 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2553 IS_INTEGRAL (RTYPE (tree))))
2555 werror (E_PLUS_INVALID, "-");
2556 goto errorTreeReturn;
2559 /* if they are both literal then */
2560 /* rewrite the tree */
2561 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2563 tree->type = EX_VALUE;
2564 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2565 valFromType (RETYPE (tree)));
2566 tree->right = tree->left = NULL;
2567 TETYPE (tree) = getSpec (TTYPE (tree) =
2568 tree->opval.val->type);
2572 /* if the left & right are equal then zero */
2573 if (isAstEqual (tree->left, tree->right))
2575 tree->type = EX_VALUE;
2576 tree->left = tree->right = NULL;
2577 tree->opval.val = constVal ("0");
2578 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2582 /* if both of them are pointers or arrays then */
2583 /* the result is going to be an integer */
2584 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2585 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2586 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2588 /* if only the left is a pointer */
2589 /* then result is a pointer */
2590 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2591 TETYPE (tree) = getSpec (TTYPE (tree) =
2594 TETYPE (tree) = getSpec (TTYPE (tree) =
2595 computeType (LTYPE (tree),
2597 LRVAL (tree) = RRVAL (tree) = 1;
2600 /*------------------------------------------------------------------*/
2601 /*----------------------------*/
2603 /*----------------------------*/
2605 /* can be only integral type */
2606 if (!IS_INTEGRAL (LTYPE (tree)))
2608 werror (E_UNARY_OP, tree->opval.op);
2609 goto errorTreeReturn;
2612 /* if left is a literal then do it */
2613 if (IS_LITERAL (LTYPE (tree)))
2615 tree->type = EX_VALUE;
2616 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2618 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2622 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2625 /*------------------------------------------------------------------*/
2626 /*----------------------------*/
2628 /*----------------------------*/
2630 /* can be pointer */
2631 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2632 !IS_PTR (LTYPE (tree)) &&
2633 !IS_ARRAY (LTYPE (tree)))
2635 werror (E_UNARY_OP, tree->opval.op);
2636 goto errorTreeReturn;
2639 /* if left is a literal then do it */
2640 if (IS_LITERAL (LTYPE (tree)))
2642 tree->type = EX_VALUE;
2643 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2645 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2649 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2652 /*------------------------------------------------------------------*/
2653 /*----------------------------*/
2655 /*----------------------------*/
2658 TTYPE (tree) = LTYPE (tree);
2659 TETYPE (tree) = LETYPE (tree);
2663 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2668 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2670 werror (E_SHIFT_OP_INVALID);
2671 werror (W_CONTINUE, "left & right types are ");
2672 printTypeChain (LTYPE (tree), stderr);
2673 fprintf (stderr, ",");
2674 printTypeChain (RTYPE (tree), stderr);
2675 fprintf (stderr, "\n");
2676 goto errorTreeReturn;
2679 /* if they are both literal then */
2680 /* rewrite the tree */
2681 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2683 tree->type = EX_VALUE;
2684 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2685 valFromType (RETYPE (tree)),
2686 (tree->opval.op == LEFT_OP ? 1 : 0));
2687 tree->right = tree->left = NULL;
2688 TETYPE (tree) = getSpec (TTYPE (tree) =
2689 tree->opval.val->type);
2693 /* a left shift must be done with at least 16bits */
2694 if ((tree->opval.op==LEFT_OP) && (getSize(LTYPE(tree))<2)) {
2696 if (IS_AST_SYM_VALUE(tree->left) || IS_AST_OP(tree->left)) {
2698 decorateType (newNode (CAST,
2699 newAst_LINK(copyLinkChain(LTYPE(tree))),
2701 SPEC_NOUN(tree->left->left->ftype)=V_INT;
2703 // must be a literal, we can do it right away
2704 SPEC_NOUN(tree->left->opval.val->type)=V_INT;
2708 /* if only the right side is a literal & we are
2709 shifting more than size of the left operand then zero */
2710 if (IS_LITERAL (RTYPE (tree)) &&
2711 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2712 (getSize (LTYPE (tree)) * 8))
2714 /* if left shift then cast up */
2715 if (tree->opval.op==LEFT_OP) {
2716 int size = getSize(LTYPE(tree));
2718 decorateType (newNode (CAST,
2719 (size == 1 ? newAst_LINK(newIntLink()) :
2720 (size == 2 ? newAst_LINK(newLongLink()) :
2721 newAst_LINK(newIntLink()))),
2724 werror (W_SHIFT_CHANGED,
2725 (tree->opval.op == LEFT_OP ? "left" : "right"));
2726 tree->type = EX_VALUE;
2727 tree->left = tree->right = NULL;
2728 tree->opval.val = constVal ("0");
2729 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2733 LRVAL (tree) = RRVAL (tree) = 1;
2734 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2736 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2740 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2744 /*------------------------------------------------------------------*/
2745 /*----------------------------*/
2747 /*----------------------------*/
2748 case CAST: /* change the type */
2749 /* cannot cast to an aggregate type */
2750 if (IS_AGGREGATE (LTYPE (tree)))
2752 werror (E_CAST_ILLEGAL);
2753 goto errorTreeReturn;
2756 /* make sure the type is complete and sane */
2757 checkTypeSanity(LETYPE(tree), "(cast)");
2760 /* if the right is a literal replace the tree */
2761 if (IS_LITERAL (RETYPE (tree))) {
2762 if (!IS_PTR (LTYPE (tree))) {
2763 tree->type = EX_VALUE;
2765 valCastLiteral (LTYPE (tree),
2766 floatFromVal (valFromType (RETYPE (tree))));
2769 TTYPE (tree) = tree->opval.val->type;
2770 tree->values.literalFromCast = 1;
2771 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2772 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2773 sym_link *rest = LTYPE(tree)->next;
2774 werror(W_LITERAL_GENERIC);
2775 TTYPE(tree) = newLink();
2776 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2777 TTYPE(tree)->next = rest;
2778 tree->left->opval.lnk = TTYPE(tree);
2781 TTYPE (tree) = LTYPE (tree);
2785 TTYPE (tree) = LTYPE (tree);
2789 #if 0 // this is already checked, now this could be explicit
2790 /* if pointer to struct then check names */
2791 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2792 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2793 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2795 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2796 SPEC_STRUCT(LETYPE(tree))->tag);
2799 /* if the right is a literal replace the tree */
2800 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2801 tree->type = EX_VALUE;
2803 valCastLiteral (LTYPE (tree),
2804 floatFromVal (valFromType (RETYPE (tree))));
2807 TTYPE (tree) = tree->opval.val->type;
2808 tree->values.literalFromCast = 1;
2810 TTYPE (tree) = LTYPE (tree);
2814 TETYPE (tree) = getSpec (TTYPE (tree));
2818 /*------------------------------------------------------------------*/
2819 /*----------------------------*/
2820 /* logical &&, || */
2821 /*----------------------------*/
2824 /* each must me arithmetic type or be a pointer */
2825 if (!IS_PTR (LTYPE (tree)) &&
2826 !IS_ARRAY (LTYPE (tree)) &&
2827 !IS_INTEGRAL (LTYPE (tree)))
2829 werror (E_COMPARE_OP);
2830 goto errorTreeReturn;
2833 if (!IS_PTR (RTYPE (tree)) &&
2834 !IS_ARRAY (RTYPE (tree)) &&
2835 !IS_INTEGRAL (RTYPE (tree)))
2837 werror (E_COMPARE_OP);
2838 goto errorTreeReturn;
2840 /* if they are both literal then */
2841 /* rewrite the tree */
2842 if (IS_LITERAL (RTYPE (tree)) &&
2843 IS_LITERAL (LTYPE (tree)))
2845 tree->type = EX_VALUE;
2846 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2847 valFromType (RETYPE (tree)),
2849 tree->right = tree->left = NULL;
2850 TETYPE (tree) = getSpec (TTYPE (tree) =
2851 tree->opval.val->type);
2854 LRVAL (tree) = RRVAL (tree) = 1;
2855 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2858 /*------------------------------------------------------------------*/
2859 /*----------------------------*/
2860 /* comparison operators */
2861 /*----------------------------*/
2869 ast *lt = optimizeCompare (tree);
2875 /* if they are pointers they must be castable */
2876 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2878 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2880 werror (E_COMPARE_OP);
2881 fprintf (stderr, "comparing type ");
2882 printTypeChain (LTYPE (tree), stderr);
2883 fprintf (stderr, "to type ");
2884 printTypeChain (RTYPE (tree), stderr);
2885 fprintf (stderr, "\n");
2886 goto errorTreeReturn;
2889 /* else they should be promotable to one another */
2892 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2893 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2895 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2897 werror (E_COMPARE_OP);
2898 fprintf (stderr, "comparing type ");
2899 printTypeChain (LTYPE (tree), stderr);
2900 fprintf (stderr, "to type ");
2901 printTypeChain (RTYPE (tree), stderr);
2902 fprintf (stderr, "\n");
2903 goto errorTreeReturn;
2906 /* if unsigned value < 0 then always false */
2907 /* if (unsigned value) > 0 then (unsigned value) */
2908 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2909 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2911 if (tree->opval.op == '<') {
2914 if (tree->opval.op == '>') {
2918 /* if they are both literal then */
2919 /* rewrite the tree */
2920 if (IS_LITERAL (RTYPE (tree)) &&
2921 IS_LITERAL (LTYPE (tree)))
2923 tree->type = EX_VALUE;
2924 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2925 valFromType (RETYPE (tree)),
2927 tree->right = tree->left = NULL;
2928 TETYPE (tree) = getSpec (TTYPE (tree) =
2929 tree->opval.val->type);
2932 LRVAL (tree) = RRVAL (tree) = 1;
2933 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2936 /*------------------------------------------------------------------*/
2937 /*----------------------------*/
2939 /*----------------------------*/
2940 case SIZEOF: /* evaluate wihout code generation */
2941 /* change the type to a integer */
2942 tree->type = EX_VALUE;
2943 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2944 tree->opval.val = constVal (buffer);
2945 tree->right = tree->left = NULL;
2946 TETYPE (tree) = getSpec (TTYPE (tree) =
2947 tree->opval.val->type);
2950 /*------------------------------------------------------------------*/
2951 /*----------------------------*/
2953 /*----------------------------*/
2955 /* return typeof enum value */
2956 tree->type = EX_VALUE;
2959 if (IS_SPEC(tree->right->ftype)) {
2960 switch (SPEC_NOUN(tree->right->ftype)) {
2962 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2963 else typeofv = TYPEOF_INT;
2966 typeofv = TYPEOF_FLOAT;
2969 typeofv = TYPEOF_CHAR;
2972 typeofv = TYPEOF_VOID;
2975 typeofv = TYPEOF_STRUCT;
2978 typeofv = TYPEOF_BIT;
2981 typeofv = TYPEOF_SBIT;
2987 switch (DCL_TYPE(tree->right->ftype)) {
2989 typeofv = TYPEOF_POINTER;
2992 typeofv = TYPEOF_FPOINTER;
2995 typeofv = TYPEOF_CPOINTER;
2998 typeofv = TYPEOF_GPOINTER;
3001 typeofv = TYPEOF_PPOINTER;
3004 typeofv = TYPEOF_IPOINTER;
3007 typeofv = TYPEOF_ARRAY;
3010 typeofv = TYPEOF_FUNCTION;
3016 sprintf (buffer, "%d", typeofv);
3017 tree->opval.val = constVal (buffer);
3018 tree->right = tree->left = NULL;
3019 TETYPE (tree) = getSpec (TTYPE (tree) =
3020 tree->opval.val->type);
3023 /*------------------------------------------------------------------*/
3024 /*----------------------------*/
3025 /* conditional operator '?' */
3026 /*----------------------------*/
3028 /* the type is value of the colon operator (on the right) */
3029 assert(IS_COLON_OP(tree->right));
3030 /* if already known then replace the tree : optimizer will do it
3031 but faster to do it here */
3032 if (IS_LITERAL (LTYPE(tree))) {
3033 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3034 return decorateType(tree->right->left) ;
3036 return decorateType(tree->right->right) ;
3039 tree->right = decorateType(tree->right);
3040 TTYPE (tree) = RTYPE(tree);
3041 TETYPE (tree) = getSpec (TTYPE (tree));
3046 /* if they don't match we have a problem */
3047 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3049 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3050 goto errorTreeReturn;
3053 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3054 TETYPE (tree) = getSpec (TTYPE (tree));
3058 #if 0 // assignment operators are converted by the parser
3059 /*------------------------------------------------------------------*/
3060 /*----------------------------*/
3061 /* assignment operators */
3062 /*----------------------------*/
3065 /* for these it must be both must be integral */
3066 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3067 !IS_ARITHMETIC (RTYPE (tree)))
3069 werror (E_OPS_INTEGRAL);
3070 goto errorTreeReturn;
3073 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3075 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3076 werror (E_CODE_WRITE, " ");
3080 werror (E_LVALUE_REQUIRED, "*= or /=");
3081 goto errorTreeReturn;
3092 /* for these it must be both must be integral */
3093 if (!IS_INTEGRAL (LTYPE (tree)) ||
3094 !IS_INTEGRAL (RTYPE (tree)))
3096 werror (E_OPS_INTEGRAL);
3097 goto errorTreeReturn;
3100 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3102 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3103 werror (E_CODE_WRITE, " ");
3107 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3108 goto errorTreeReturn;
3114 /*------------------------------------------------------------------*/
3115 /*----------------------------*/
3117 /*----------------------------*/
3119 if (!(IS_PTR (LTYPE (tree)) ||
3120 IS_ARITHMETIC (LTYPE (tree))))
3122 werror (E_PLUS_INVALID, "-=");
3123 goto errorTreeReturn;
3126 if (!(IS_PTR (RTYPE (tree)) ||
3127 IS_ARITHMETIC (RTYPE (tree))))
3129 werror (E_PLUS_INVALID, "-=");
3130 goto errorTreeReturn;
3133 TETYPE (tree) = getSpec (TTYPE (tree) =
3134 computeType (LTYPE (tree),
3137 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3138 werror (E_CODE_WRITE, " ");
3142 werror (E_LVALUE_REQUIRED, "-=");
3143 goto errorTreeReturn;
3149 /*------------------------------------------------------------------*/
3150 /*----------------------------*/
3152 /*----------------------------*/
3154 /* this is not a unary operation */
3155 /* if both pointers then problem */
3156 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3158 werror (E_PTR_PLUS_PTR);
3159 goto errorTreeReturn;
3162 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3164 werror (E_PLUS_INVALID, "+=");
3165 goto errorTreeReturn;
3168 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3170 werror (E_PLUS_INVALID, "+=");
3171 goto errorTreeReturn;
3174 TETYPE (tree) = getSpec (TTYPE (tree) =
3175 computeType (LTYPE (tree),
3178 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3179 werror (E_CODE_WRITE, " ");
3183 werror (E_LVALUE_REQUIRED, "+=");
3184 goto errorTreeReturn;
3187 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3188 tree->opval.op = '=';
3193 /*------------------------------------------------------------------*/
3194 /*----------------------------*/
3195 /* straight assignemnt */
3196 /*----------------------------*/
3198 /* cannot be an aggregate */
3199 if (IS_AGGREGATE (LTYPE (tree)))
3201 werror (E_AGGR_ASSIGN);
3202 goto errorTreeReturn;
3205 /* they should either match or be castable */
3206 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3208 werror (E_TYPE_MISMATCH, "assignment", " ");
3209 printFromToType(RTYPE(tree),LTYPE(tree));
3210 //goto errorTreeReturn;
3213 /* if the left side of the tree is of type void
3214 then report error */
3215 if (IS_VOID (LTYPE (tree)))
3217 werror (E_CAST_ZERO);
3218 printFromToType(RTYPE(tree), LTYPE(tree));
3221 TETYPE (tree) = getSpec (TTYPE (tree) =
3225 if (!tree->initMode ) {
3226 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3227 werror (E_CODE_WRITE, " ");
3231 werror (E_LVALUE_REQUIRED, "=");
3232 goto errorTreeReturn;
3237 /*------------------------------------------------------------------*/
3238 /*----------------------------*/
3239 /* comma operator */
3240 /*----------------------------*/
3242 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3245 /*------------------------------------------------------------------*/
3246 /*----------------------------*/
3248 /*----------------------------*/
3252 if (processParms (tree->left,
3253 FUNC_ARGS(tree->left->ftype),
3254 tree->right, &parmNumber, TRUE)) {
3255 goto errorTreeReturn;
3258 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3259 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3261 //FUNC_ARGS(tree->left->ftype) =
3262 //reverseVal (FUNC_ARGS(tree->left->ftype));
3263 reverseParms (tree->right);
3266 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3269 /*------------------------------------------------------------------*/
3270 /*----------------------------*/
3271 /* return statement */
3272 /*----------------------------*/
3277 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3279 werror (W_RETURN_MISMATCH);
3280 printFromToType (RTYPE(tree), currFunc->type->next);
3281 goto errorTreeReturn;
3284 if (IS_VOID (currFunc->type->next)
3286 !IS_VOID (RTYPE (tree)))
3288 werror (E_FUNC_VOID);
3289 goto errorTreeReturn;
3292 /* if there is going to be a casing required then add it */
3293 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3296 decorateType (newNode (CAST,
3297 newAst_LINK (copyLinkChain (currFunc->type->next)),
3306 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3308 werror (E_VOID_FUNC, currFunc->name);
3309 goto errorTreeReturn;
3312 TTYPE (tree) = TETYPE (tree) = NULL;
3315 /*------------------------------------------------------------------*/
3316 /*----------------------------*/
3317 /* switch statement */
3318 /*----------------------------*/
3320 /* the switch value must be an integer */
3321 if (!IS_INTEGRAL (LTYPE (tree)))
3323 werror (E_SWITCH_NON_INTEGER);
3324 goto errorTreeReturn;
3327 TTYPE (tree) = TETYPE (tree) = NULL;
3330 /*------------------------------------------------------------------*/
3331 /*----------------------------*/
3333 /*----------------------------*/
3335 tree->left = backPatchLabels (tree->left,
3338 TTYPE (tree) = TETYPE (tree) = NULL;
3341 /*------------------------------------------------------------------*/
3342 /*----------------------------*/
3344 /*----------------------------*/
3347 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3348 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3349 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3351 /* if the for loop is reversible then
3352 reverse it otherwise do what we normally
3358 if (isLoopReversible (tree, &sym, &init, &end))
3359 return reverseLoop (tree, sym, init, end);
3361 return decorateType (createFor (AST_FOR (tree, trueLabel),
3362 AST_FOR (tree, continueLabel),
3363 AST_FOR (tree, falseLabel),
3364 AST_FOR (tree, condLabel),
3365 AST_FOR (tree, initExpr),
3366 AST_FOR (tree, condExpr),
3367 AST_FOR (tree, loopExpr),
3371 TTYPE (tree) = TETYPE (tree) = NULL;
3375 /* some error found this tree will be killed */
3377 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3378 tree->opval.op = NULLOP;
3384 /*-----------------------------------------------------------------*/
3385 /* sizeofOp - processes size of operation */
3386 /*-----------------------------------------------------------------*/
3388 sizeofOp (sym_link * type)
3392 /* make sure the type is complete and sane */
3393 checkTypeSanity(type, "(sizeof)");
3395 /* get the size and convert it to character */
3396 sprintf (buff, "%d", getSize (type));
3398 /* now convert into value */
3399 return constVal (buff);
3403 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3404 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3405 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3406 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3407 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3408 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3409 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3411 /*-----------------------------------------------------------------*/
3412 /* backPatchLabels - change and or not operators to flow control */
3413 /*-----------------------------------------------------------------*/
3415 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3421 if (!(IS_ANDORNOT (tree)))
3424 /* if this an and */
3427 static int localLbl = 0;
3430 sprintf (buffer, "_and_%d", localLbl++);
3431 localLabel = newSymbol (buffer, NestLevel);
3433 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3435 /* if left is already a IFX then just change the if true label in that */
3436 if (!IS_IFX (tree->left))
3437 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3439 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3440 /* right is a IFX then just join */
3441 if (IS_IFX (tree->right))
3442 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3444 tree->right = createLabel (localLabel, tree->right);
3445 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3447 return newNode (NULLOP, tree->left, tree->right);
3450 /* if this is an or operation */
3453 static int localLbl = 0;
3456 sprintf (buffer, "_or_%d", localLbl++);
3457 localLabel = newSymbol (buffer, NestLevel);
3459 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3461 /* if left is already a IFX then just change the if true label in that */
3462 if (!IS_IFX (tree->left))
3463 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3465 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3466 /* right is a IFX then just join */
3467 if (IS_IFX (tree->right))
3468 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3470 tree->right = createLabel (localLabel, tree->right);
3471 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3473 return newNode (NULLOP, tree->left, tree->right);
3479 int wasnot = IS_NOT (tree->left);
3480 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3482 /* if the left is already a IFX */
3483 if (!IS_IFX (tree->left))
3484 tree->left = newNode (IFX, tree->left, NULL);
3488 tree->left->trueLabel = trueLabel;
3489 tree->left->falseLabel = falseLabel;
3493 tree->left->trueLabel = falseLabel;
3494 tree->left->falseLabel = trueLabel;
3501 tree->trueLabel = trueLabel;
3502 tree->falseLabel = falseLabel;
3509 /*-----------------------------------------------------------------*/
3510 /* createBlock - create expression tree for block */
3511 /*-----------------------------------------------------------------*/
3513 createBlock (symbol * decl, ast * body)
3517 /* if the block has nothing */
3521 ex = newNode (BLOCK, NULL, body);
3522 ex->values.sym = decl;
3524 ex->right = ex->right;
3530 /*-----------------------------------------------------------------*/
3531 /* createLabel - creates the expression tree for labels */
3532 /*-----------------------------------------------------------------*/
3534 createLabel (symbol * label, ast * stmnt)
3537 char name[SDCC_NAME_MAX + 1];
3540 /* must create fresh symbol if the symbol name */
3541 /* exists in the symbol table, since there can */
3542 /* be a variable with the same name as the labl */
3543 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3544 (csym->level == label->level))
3545 label = newSymbol (label->name, label->level);
3547 /* change the name before putting it in add _ */
3548 sprintf (name, "%s", label->name);
3550 /* put the label in the LabelSymbol table */
3551 /* but first check if a label of the same */
3553 if ((csym = findSym (LabelTab, NULL, name)))
3554 werror (E_DUPLICATE_LABEL, label->name);
3556 addSym (LabelTab, label, name, label->level, 0, 0);
3559 label->key = labelKey++;
3560 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3566 /*-----------------------------------------------------------------*/
3567 /* createCase - generates the parsetree for a case statement */
3568 /*-----------------------------------------------------------------*/
3570 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3572 char caseLbl[SDCC_NAME_MAX + 1];
3576 /* if the switch statement does not exist */
3577 /* then case is out of context */
3580 werror (E_CASE_CONTEXT);
3584 caseVal = decorateType (resolveSymbols (caseVal));
3585 /* if not a constant then error */
3586 if (!IS_LITERAL (caseVal->ftype))
3588 werror (E_CASE_CONSTANT);
3592 /* if not a integer than error */
3593 if (!IS_INTEGRAL (caseVal->ftype))
3595 werror (E_CASE_NON_INTEGER);
3599 /* find the end of the switch values chain */
3600 if (!(val = swStat->values.switchVals.swVals))
3601 swStat->values.switchVals.swVals = caseVal->opval.val;
3604 /* also order the cases according to value */
3606 int cVal = (int) floatFromVal (caseVal->opval.val);
3607 while (val && (int) floatFromVal (val) < cVal)
3613 /* if we reached the end then */
3616 pval->next = caseVal->opval.val;
3620 /* we found a value greater than */
3621 /* the current value we must add this */
3622 /* before the value */
3623 caseVal->opval.val->next = val;
3625 /* if this was the first in chain */
3626 if (swStat->values.switchVals.swVals == val)
3627 swStat->values.switchVals.swVals =
3630 pval->next = caseVal->opval.val;
3635 /* create the case label */
3636 sprintf (caseLbl, "_case_%d_%d",
3637 swStat->values.switchVals.swNum,
3638 (int) floatFromVal (caseVal->opval.val));
3640 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3645 /*-----------------------------------------------------------------*/
3646 /* createDefault - creates the parse tree for the default statement */
3647 /*-----------------------------------------------------------------*/
3649 createDefault (ast * swStat, ast * stmnt)
3651 char defLbl[SDCC_NAME_MAX + 1];
3653 /* if the switch statement does not exist */
3654 /* then case is out of context */
3657 werror (E_CASE_CONTEXT);
3661 /* turn on the default flag */
3662 swStat->values.switchVals.swDefault = 1;
3664 /* create the label */
3665 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3666 return createLabel (newSymbol (defLbl, 0), stmnt);
3669 /*-----------------------------------------------------------------*/
3670 /* createIf - creates the parsetree for the if statement */
3671 /*-----------------------------------------------------------------*/
3673 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3675 static int Lblnum = 0;
3677 symbol *ifTrue, *ifFalse, *ifEnd;
3679 /* if neither exists */
3680 if (!elseBody && !ifBody) {
3681 // if there are no side effects (i++, j() etc)
3682 if (!hasSEFcalls(condAst)) {
3687 /* create the labels */
3688 sprintf (buffer, "_iffalse_%d", Lblnum);
3689 ifFalse = newSymbol (buffer, NestLevel);
3690 /* if no else body then end == false */
3695 sprintf (buffer, "_ifend_%d", Lblnum);
3696 ifEnd = newSymbol (buffer, NestLevel);
3699 sprintf (buffer, "_iftrue_%d", Lblnum);
3700 ifTrue = newSymbol (buffer, NestLevel);
3704 /* attach the ifTrue label to the top of it body */
3705 ifBody = createLabel (ifTrue, ifBody);
3706 /* attach a goto end to the ifBody if else is present */
3709 ifBody = newNode (NULLOP, ifBody,
3711 newAst_VALUE (symbolVal (ifEnd)),
3713 /* put the elseLabel on the else body */
3714 elseBody = createLabel (ifFalse, elseBody);
3715 /* out the end at the end of the body */
3716 elseBody = newNode (NULLOP,
3718 createLabel (ifEnd, NULL));
3722 ifBody = newNode (NULLOP, ifBody,
3723 createLabel (ifFalse, NULL));
3725 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3726 if (IS_IFX (condAst))
3729 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3731 return newNode (NULLOP, ifTree,
3732 newNode (NULLOP, ifBody, elseBody));
3736 /*-----------------------------------------------------------------*/
3737 /* createDo - creates parse tree for do */
3740 /* _docontinue_n: */
3741 /* condition_expression +-> trueLabel -> _dobody_n */
3743 /* +-> falseLabel-> _dobreak_n */
3745 /*-----------------------------------------------------------------*/
3747 createDo (symbol * trueLabel, symbol * continueLabel,
3748 symbol * falseLabel, ast * condAst, ast * doBody)
3753 /* if the body does not exist then it is simple */
3756 condAst = backPatchLabels (condAst, continueLabel, NULL);
3757 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3758 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3759 doTree->trueLabel = continueLabel;
3760 doTree->falseLabel = NULL;
3764 /* otherwise we have a body */
3765 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3767 /* attach the body label to the top */
3768 doBody = createLabel (trueLabel, doBody);
3769 /* attach the continue label to end of body */
3770 doBody = newNode (NULLOP, doBody,
3771 createLabel (continueLabel, NULL));
3773 /* now put the break label at the end */
3774 if (IS_IFX (condAst))
3777 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3779 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3781 /* putting it together */
3782 return newNode (NULLOP, doBody, doTree);
3785 /*-----------------------------------------------------------------*/
3786 /* createFor - creates parse tree for 'for' statement */
3789 /* condExpr +-> trueLabel -> _forbody_n */
3791 /* +-> falseLabel-> _forbreak_n */
3794 /* _forcontinue_n: */
3796 /* goto _forcond_n ; */
3798 /*-----------------------------------------------------------------*/
3800 createFor (symbol * trueLabel, symbol * continueLabel,
3801 symbol * falseLabel, symbol * condLabel,
3802 ast * initExpr, ast * condExpr, ast * loopExpr,
3807 /* if loopexpression not present then we can generate it */
3808 /* the same way as a while */
3810 return newNode (NULLOP, initExpr,
3811 createWhile (trueLabel, continueLabel,
3812 falseLabel, condExpr, forBody));
3813 /* vanilla for statement */
3814 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3816 if (condExpr && !IS_IFX (condExpr))
3817 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3820 /* attach condition label to condition */
3821 condExpr = createLabel (condLabel, condExpr);
3823 /* attach body label to body */
3824 forBody = createLabel (trueLabel, forBody);
3826 /* attach continue to forLoop expression & attach */
3827 /* goto the forcond @ and of loopExpression */
3828 loopExpr = createLabel (continueLabel,
3832 newAst_VALUE (symbolVal (condLabel)),
3834 /* now start putting them together */
3835 forTree = newNode (NULLOP, initExpr, condExpr);
3836 forTree = newNode (NULLOP, forTree, forBody);
3837 forTree = newNode (NULLOP, forTree, loopExpr);
3838 /* finally add the break label */
3839 forTree = newNode (NULLOP, forTree,
3840 createLabel (falseLabel, NULL));
3844 /*-----------------------------------------------------------------*/
3845 /* createWhile - creates parse tree for while statement */
3846 /* the while statement will be created as follows */
3848 /* _while_continue_n: */
3849 /* condition_expression +-> trueLabel -> _while_boby_n */
3851 /* +-> falseLabel -> _while_break_n */
3852 /* _while_body_n: */
3854 /* goto _while_continue_n */
3855 /* _while_break_n: */
3856 /*-----------------------------------------------------------------*/
3858 createWhile (symbol * trueLabel, symbol * continueLabel,
3859 symbol * falseLabel, ast * condExpr, ast * whileBody)
3863 /* put the continue label */
3864 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3865 condExpr = createLabel (continueLabel, condExpr);
3866 condExpr->lineno = 0;
3868 /* put the body label in front of the body */
3869 whileBody = createLabel (trueLabel, whileBody);
3870 whileBody->lineno = 0;
3871 /* put a jump to continue at the end of the body */
3872 /* and put break label at the end of the body */
3873 whileBody = newNode (NULLOP,
3876 newAst_VALUE (symbolVal (continueLabel)),
3877 createLabel (falseLabel, NULL)));
3879 /* put it all together */
3880 if (IS_IFX (condExpr))
3881 whileTree = condExpr;
3884 whileTree = newNode (IFX, condExpr, NULL);
3885 /* put the true & false labels in place */
3886 whileTree->trueLabel = trueLabel;
3887 whileTree->falseLabel = falseLabel;
3890 return newNode (NULLOP, whileTree, whileBody);
3893 /*-----------------------------------------------------------------*/
3894 /* optimizeGetHbit - get highest order bit of the expression */
3895 /*-----------------------------------------------------------------*/
3897 optimizeGetHbit (ast * tree)
3900 /* if this is not a bit and */
3901 if (!IS_BITAND (tree))
3904 /* will look for tree of the form
3905 ( expr >> ((sizeof expr) -1) ) & 1 */
3906 if (!IS_AST_LIT_VALUE (tree->right))
3909 if (AST_LIT_VALUE (tree->right) != 1)
3912 if (!IS_RIGHT_OP (tree->left))
3915 if (!IS_AST_LIT_VALUE (tree->left->right))
3918 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3919 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3922 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3926 /*-----------------------------------------------------------------*/
3927 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3928 /*-----------------------------------------------------------------*/
3930 optimizeRRCRLC (ast * root)
3932 /* will look for trees of the form
3933 (?expr << 1) | (?expr >> 7) or
3934 (?expr >> 7) | (?expr << 1) will make that
3935 into a RLC : operation ..
3937 (?expr >> 1) | (?expr << 7) or
3938 (?expr << 7) | (?expr >> 1) will make that
3939 into a RRC operation
3940 note : by 7 I mean (number of bits required to hold the
3942 /* if the root operations is not a | operation the not */
3943 if (!IS_BITOR (root))
3946 /* I have to think of a better way to match patterns this sucks */
3947 /* that aside let start looking for the first case : I use a the
3948 negative check a lot to improve the efficiency */
3949 /* (?expr << 1) | (?expr >> 7) */
3950 if (IS_LEFT_OP (root->left) &&
3951 IS_RIGHT_OP (root->right))
3954 if (!SPEC_USIGN (TETYPE (root->left->left)))
3957 if (!IS_AST_LIT_VALUE (root->left->right) ||
3958 !IS_AST_LIT_VALUE (root->right->right))
3961 /* make sure it is the same expression */
3962 if (!isAstEqual (root->left->left,
3966 if (AST_LIT_VALUE (root->left->right) != 1)
3969 if (AST_LIT_VALUE (root->right->right) !=
3970 (getSize (TTYPE (root->left->left)) * 8 - 1))
3973 /* whew got the first case : create the AST */
3974 return newNode (RLC, root->left->left, NULL);
3978 /* check for second case */
3979 /* (?expr >> 7) | (?expr << 1) */
3980 if (IS_LEFT_OP (root->right) &&
3981 IS_RIGHT_OP (root->left))
3984 if (!SPEC_USIGN (TETYPE (root->left->left)))
3987 if (!IS_AST_LIT_VALUE (root->left->right) ||
3988 !IS_AST_LIT_VALUE (root->right->right))
3991 /* make sure it is the same symbol */
3992 if (!isAstEqual (root->left->left,
3996 if (AST_LIT_VALUE (root->right->right) != 1)
3999 if (AST_LIT_VALUE (root->left->right) !=
4000 (getSize (TTYPE (root->left->left)) * 8 - 1))
4003 /* whew got the first case : create the AST */
4004 return newNode (RLC, root->left->left, NULL);
4009 /* third case for RRC */
4010 /* (?symbol >> 1) | (?symbol << 7) */
4011 if (IS_LEFT_OP (root->right) &&
4012 IS_RIGHT_OP (root->left))
4015 if (!SPEC_USIGN (TETYPE (root->left->left)))
4018 if (!IS_AST_LIT_VALUE (root->left->right) ||
4019 !IS_AST_LIT_VALUE (root->right->right))
4022 /* make sure it is the same symbol */
4023 if (!isAstEqual (root->left->left,
4027 if (AST_LIT_VALUE (root->left->right) != 1)
4030 if (AST_LIT_VALUE (root->right->right) !=
4031 (getSize (TTYPE (root->left->left)) * 8 - 1))
4034 /* whew got the first case : create the AST */
4035 return newNode (RRC, root->left->left, NULL);
4039 /* fourth and last case for now */
4040 /* (?symbol << 7) | (?symbol >> 1) */
4041 if (IS_RIGHT_OP (root->right) &&
4042 IS_LEFT_OP (root->left))
4045 if (!SPEC_USIGN (TETYPE (root->left->left)))
4048 if (!IS_AST_LIT_VALUE (root->left->right) ||
4049 !IS_AST_LIT_VALUE (root->right->right))
4052 /* make sure it is the same symbol */
4053 if (!isAstEqual (root->left->left,
4057 if (AST_LIT_VALUE (root->right->right) != 1)
4060 if (AST_LIT_VALUE (root->left->right) !=
4061 (getSize (TTYPE (root->left->left)) * 8 - 1))
4064 /* whew got the first case : create the AST */
4065 return newNode (RRC, root->left->left, NULL);
4069 /* not found return root */
4073 /*-----------------------------------------------------------------*/
4074 /* optimizeCompare - otimizes compares for bit variables */
4075 /*-----------------------------------------------------------------*/
4077 optimizeCompare (ast * root)
4079 ast *optExpr = NULL;
4082 unsigned int litValue;
4084 /* if nothing then return nothing */
4088 /* if not a compare op then do leaves */
4089 if (!IS_COMPARE_OP (root))
4091 root->left = optimizeCompare (root->left);
4092 root->right = optimizeCompare (root->right);
4096 /* if left & right are the same then depending
4097 of the operation do */
4098 if (isAstEqual (root->left, root->right))
4100 switch (root->opval.op)
4105 optExpr = newAst_VALUE (constVal ("0"));
4110 optExpr = newAst_VALUE (constVal ("1"));
4114 return decorateType (optExpr);
4117 vleft = (root->left->type == EX_VALUE ?
4118 root->left->opval.val : NULL);
4120 vright = (root->right->type == EX_VALUE ?
4121 root->right->opval.val : NULL);
4123 /* if left is a BITVAR in BITSPACE */
4124 /* and right is a LITERAL then opt- */
4125 /* imize else do nothing */
4126 if (vleft && vright &&
4127 IS_BITVAR (vleft->etype) &&
4128 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4129 IS_LITERAL (vright->etype))
4132 /* if right side > 1 then comparison may never succeed */
4133 if ((litValue = (int) floatFromVal (vright)) > 1)
4135 werror (W_BAD_COMPARE);
4141 switch (root->opval.op)
4143 case '>': /* bit value greater than 1 cannot be */
4144 werror (W_BAD_COMPARE);
4148 case '<': /* bit value < 1 means 0 */
4150 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4153 case LE_OP: /* bit value <= 1 means no check */
4154 optExpr = newAst_VALUE (vright);
4157 case GE_OP: /* bit value >= 1 means only check for = */
4159 optExpr = newAst_VALUE (vleft);
4164 { /* literal is zero */
4165 switch (root->opval.op)
4167 case '<': /* bit value < 0 cannot be */
4168 werror (W_BAD_COMPARE);
4172 case '>': /* bit value > 0 means 1 */
4174 optExpr = newAst_VALUE (vleft);
4177 case LE_OP: /* bit value <= 0 means no check */
4178 case GE_OP: /* bit value >= 0 means no check */
4179 werror (W_BAD_COMPARE);
4183 case EQ_OP: /* bit == 0 means ! of bit */
4184 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4188 return decorateType (resolveSymbols (optExpr));
4189 } /* end-of-if of BITVAR */
4194 /*-----------------------------------------------------------------*/
4195 /* addSymToBlock : adds the symbol to the first block we find */
4196 /*-----------------------------------------------------------------*/
4198 addSymToBlock (symbol * sym, ast * tree)
4200 /* reached end of tree or a leaf */
4201 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4205 if (IS_AST_OP (tree) &&
4206 tree->opval.op == BLOCK)
4209 symbol *lsym = copySymbol (sym);
4211 lsym->next = AST_VALUES (tree, sym);
4212 AST_VALUES (tree, sym) = lsym;
4216 addSymToBlock (sym, tree->left);
4217 addSymToBlock (sym, tree->right);
4220 /*-----------------------------------------------------------------*/
4221 /* processRegParms - do processing for register parameters */
4222 /*-----------------------------------------------------------------*/
4224 processRegParms (value * args, ast * body)
4228 if (IS_REGPARM (args->etype))
4229 addSymToBlock (args->sym, body);
4234 /*-----------------------------------------------------------------*/
4235 /* resetParmKey - resets the operandkeys for the symbols */
4236 /*-----------------------------------------------------------------*/
4237 DEFSETFUNC (resetParmKey)
4248 /*-----------------------------------------------------------------*/
4249 /* createFunction - This is the key node that calls the iCode for */
4250 /* generating the code for a function. Note code */
4251 /* is generated function by function, later when */
4252 /* add inter-procedural analysis this will change */
4253 /*-----------------------------------------------------------------*/
4255 createFunction (symbol * name, ast * body)
4261 iCode *piCode = NULL;
4263 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4264 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4266 /* if check function return 0 then some problem */
4267 if (checkFunction (name, NULL) == 0)
4270 /* create a dummy block if none exists */
4272 body = newNode (BLOCK, NULL, NULL);
4276 /* check if the function name already in the symbol table */
4277 if ((csym = findSym (SymbolTab, NULL, name->name)))
4280 /* special case for compiler defined functions
4281 we need to add the name to the publics list : this
4282 actually means we are now compiling the compiler
4286 addSet (&publics, name);
4292 allocVariables (name);
4294 name->lastLine = yylineno;
4297 /* set the stack pointer */
4298 /* PENDING: check this for the mcs51 */
4299 stackPtr = -port->stack.direction * port->stack.call_overhead;
4300 if (IFFUNC_ISISR (name->type))
4301 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4302 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4303 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4305 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4307 fetype = getSpec (name->type); /* get the specifier for the function */
4308 /* if this is a reentrant function then */
4309 if (IFFUNC_ISREENT (name->type))
4312 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4314 /* do processing for parameters that are passed in registers */
4315 processRegParms (FUNC_ARGS(name->type), body);
4317 /* set the stack pointer */
4321 /* allocate & autoinit the block variables */
4322 processBlockVars (body, &stack, ALLOCATE);
4324 /* save the stack information */
4325 if (options.useXstack)
4326 name->xstack = SPEC_STAK (fetype) = stack;
4328 name->stack = SPEC_STAK (fetype) = stack;
4330 /* name needs to be mangled */
4331 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4333 body = resolveSymbols (body); /* resolve the symbols */
4334 body = decorateType (body); /* propagateType & do semantic checks */
4336 ex = newAst_VALUE (symbolVal (name)); /* create name */
4337 ex = newNode (FUNCTION, ex, body);
4338 ex->values.args = FUNC_ARGS(name->type);
4340 if (options.dump_tree) PA(ex);
4343 werror (E_FUNC_NO_CODE, name->name);
4347 /* create the node & generate intermediate code */
4349 codeOutFile = code->oFile;
4350 piCode = iCodeFromAst (ex);
4354 werror (E_FUNC_NO_CODE, name->name);
4358 eBBlockFromiCode (piCode);
4360 /* if there are any statics then do them */
4363 GcurMemmap = statsg;
4364 codeOutFile = statsg->oFile;
4365 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4371 /* dealloc the block variables */
4372 processBlockVars (body, &stack, DEALLOCATE);
4373 /* deallocate paramaters */
4374 deallocParms (FUNC_ARGS(name->type));
4376 if (IFFUNC_ISREENT (name->type))
4379 /* we are done freeup memory & cleanup */
4381 if (port->reset_labelKey) labelKey = 1;
4383 FUNC_HASBODY(name->type) = 1;
4384 addSet (&operKeyReset, name);
4385 applyToSet (operKeyReset, resetParmKey);
4388 cdbStructBlock (1, cdbFile);
4390 cleanUpLevel (LabelTab, 0);
4391 cleanUpBlock (StructTab, 1);
4392 cleanUpBlock (TypedefTab, 1);
4394 xstack->syms = NULL;
4395 istack->syms = NULL;
4400 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4401 /*-----------------------------------------------------------------*/
4402 /* ast_print : prints the ast (for debugging purposes) */
4403 /*-----------------------------------------------------------------*/
4405 void ast_print (ast * tree, FILE *outfile, int indent)
4410 /* can print only decorated trees */
4411 if (!tree->decorated) return;
4413 /* if any child is an error | this one is an error do nothing */
4414 if (tree->isError ||
4415 (tree->left && tree->left->isError) ||
4416 (tree->right && tree->right->isError)) {
4417 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4421 /* print the line */
4422 /* if not block & function */
4423 if (tree->type == EX_OP &&
4424 (tree->opval.op != FUNCTION &&
4425 tree->opval.op != BLOCK &&
4426 tree->opval.op != NULLOP)) {
4429 if (tree->opval.op == FUNCTION) {
4431 value *args=FUNC_ARGS(tree->left->opval.val->type);
4432 fprintf(outfile,"FUNCTION (%s=%p) type (",
4433 tree->left->opval.val->name, tree);
4434 printTypeChain (tree->ftype,outfile);
4435 fprintf(outfile,") args (");
4438 fprintf (outfile, ", ");
4440 printTypeChain (args ? args->type : NULL, outfile);
4442 args= args ? args->next : NULL;
4444 fprintf(outfile,")\n");
4445 ast_print(tree->left,outfile,indent);
4446 ast_print(tree->right,outfile,indent);
4449 if (tree->opval.op == BLOCK) {
4450 symbol *decls = tree->values.sym;
4451 INDENT(indent,outfile);
4452 fprintf(outfile,"{\n");
4454 INDENT(indent+2,outfile);
4455 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4456 decls->name, decls);
4457 printTypeChain(decls->type,outfile);
4458 fprintf(outfile,")\n");
4460 decls = decls->next;
4462 ast_print(tree->right,outfile,indent+2);
4463 INDENT(indent,outfile);
4464 fprintf(outfile,"}\n");
4467 if (tree->opval.op == NULLOP) {
4468 fprintf(outfile,"\n");
4469 ast_print(tree->left,outfile,indent);
4470 fprintf(outfile,"\n");
4471 ast_print(tree->right,outfile,indent);
4474 INDENT(indent,outfile);
4476 /*------------------------------------------------------------------*/
4477 /*----------------------------*/
4478 /* leaf has been reached */
4479 /*----------------------------*/
4480 /* if this is of type value */
4481 /* just get the type */
4482 if (tree->type == EX_VALUE) {
4484 if (IS_LITERAL (tree->opval.val->etype)) {
4485 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4486 (int) floatFromVal(tree->opval.val),
4487 (int) floatFromVal(tree->opval.val),
4488 floatFromVal(tree->opval.val));
4489 } else if (tree->opval.val->sym) {
4490 /* if the undefined flag is set then give error message */
4491 if (tree->opval.val->sym->undefined) {
4492 fprintf(outfile,"UNDEFINED SYMBOL ");
4494 fprintf(outfile,"SYMBOL ");
4496 fprintf(outfile,"(%s=%p)",
4497 tree->opval.val->sym->name,tree);
4500 fprintf(outfile," type (");
4501 printTypeChain(tree->ftype,outfile);
4502 fprintf(outfile,")\n");
4504 fprintf(outfile,"\n");
4509 /* if type link for the case of cast */
4510 if (tree->type == EX_LINK) {
4511 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4512 printTypeChain(tree->opval.lnk,outfile);
4513 fprintf(outfile,")\n");
4518 /* depending on type of operator do */
4520 switch (tree->opval.op) {
4521 /*------------------------------------------------------------------*/
4522 /*----------------------------*/
4524 /*----------------------------*/
4526 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4527 printTypeChain(tree->ftype,outfile);
4528 fprintf(outfile,")\n");
4529 ast_print(tree->left,outfile,indent+2);
4530 ast_print(tree->right,outfile,indent+2);
4533 /*------------------------------------------------------------------*/
4534 /*----------------------------*/
4536 /*----------------------------*/
4538 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4539 printTypeChain(tree->ftype,outfile);
4540 fprintf(outfile,")\n");
4541 ast_print(tree->left,outfile,indent+2);
4542 ast_print(tree->right,outfile,indent+2);
4545 /*------------------------------------------------------------------*/
4546 /*----------------------------*/
4547 /* struct/union pointer */
4548 /*----------------------------*/
4550 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4551 printTypeChain(tree->ftype,outfile);
4552 fprintf(outfile,")\n");
4553 ast_print(tree->left,outfile,indent+2);
4554 ast_print(tree->right,outfile,indent+2);
4557 /*------------------------------------------------------------------*/
4558 /*----------------------------*/
4559 /* ++/-- operation */
4560 /*----------------------------*/
4561 case INC_OP: /* incerement operator unary so left only */
4562 fprintf(outfile,"INC_OP (%p) type (",tree);
4563 printTypeChain(tree->ftype,outfile);
4564 fprintf(outfile,")\n");
4565 ast_print(tree->left,outfile,indent+2);
4569 fprintf(outfile,"DEC_OP (%p) type (",tree);
4570 printTypeChain(tree->ftype,outfile);
4571 fprintf(outfile,")\n");
4572 ast_print(tree->left,outfile,indent+2);
4575 /*------------------------------------------------------------------*/
4576 /*----------------------------*/
4578 /*----------------------------*/
4581 fprintf(outfile,"& (%p) type (",tree);
4582 printTypeChain(tree->ftype,outfile);
4583 fprintf(outfile,")\n");
4584 ast_print(tree->left,outfile,indent+2);
4585 ast_print(tree->right,outfile,indent+2);
4587 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4588 printTypeChain(tree->ftype,outfile);
4589 fprintf(outfile,")\n");
4590 ast_print(tree->left,outfile,indent+2);
4591 ast_print(tree->right,outfile,indent+2);
4594 /*----------------------------*/
4596 /*----------------------------*/
4598 fprintf(outfile,"OR (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+2);
4602 ast_print(tree->right,outfile,indent+2);
4604 /*------------------------------------------------------------------*/
4605 /*----------------------------*/
4607 /*----------------------------*/
4609 fprintf(outfile,"XOR (%p) type (",tree);
4610 printTypeChain(tree->ftype,outfile);
4611 fprintf(outfile,")\n");
4612 ast_print(tree->left,outfile,indent+2);
4613 ast_print(tree->right,outfile,indent+2);
4616 /*------------------------------------------------------------------*/
4617 /*----------------------------*/
4619 /*----------------------------*/
4621 fprintf(outfile,"DIV (%p) type (",tree);
4622 printTypeChain(tree->ftype,outfile);
4623 fprintf(outfile,")\n");
4624 ast_print(tree->left,outfile,indent+2);
4625 ast_print(tree->right,outfile,indent+2);
4627 /*------------------------------------------------------------------*/
4628 /*----------------------------*/
4630 /*----------------------------*/
4632 fprintf(outfile,"MOD (%p) type (",tree);
4633 printTypeChain(tree->ftype,outfile);
4634 fprintf(outfile,")\n");
4635 ast_print(tree->left,outfile,indent+2);
4636 ast_print(tree->right,outfile,indent+2);
4639 /*------------------------------------------------------------------*/
4640 /*----------------------------*/
4641 /* address dereference */
4642 /*----------------------------*/
4643 case '*': /* can be unary : if right is null then unary operation */
4645 fprintf(outfile,"DEREF (%p) type (",tree);
4646 printTypeChain(tree->ftype,outfile);
4647 fprintf(outfile,")\n");
4648 ast_print(tree->left,outfile,indent+2);
4651 /*------------------------------------------------------------------*/
4652 /*----------------------------*/
4653 /* multiplication */
4654 /*----------------------------*/
4655 fprintf(outfile,"MULT (%p) type (",tree);
4656 printTypeChain(tree->ftype,outfile);
4657 fprintf(outfile,")\n");
4658 ast_print(tree->left,outfile,indent+2);
4659 ast_print(tree->right,outfile,indent+2);
4663 /*------------------------------------------------------------------*/
4664 /*----------------------------*/
4665 /* unary '+' operator */
4666 /*----------------------------*/
4670 fprintf(outfile,"UPLUS (%p) type (",tree);
4671 printTypeChain(tree->ftype,outfile);
4672 fprintf(outfile,")\n");
4673 ast_print(tree->left,outfile,indent+2);
4675 /*------------------------------------------------------------------*/
4676 /*----------------------------*/
4678 /*----------------------------*/
4679 fprintf(outfile,"ADD (%p) type (",tree);
4680 printTypeChain(tree->ftype,outfile);
4681 fprintf(outfile,")\n");
4682 ast_print(tree->left,outfile,indent+2);
4683 ast_print(tree->right,outfile,indent+2);
4686 /*------------------------------------------------------------------*/
4687 /*----------------------------*/
4689 /*----------------------------*/
4690 case '-': /* can be unary */
4692 fprintf(outfile,"UMINUS (%p) type (",tree);
4693 printTypeChain(tree->ftype,outfile);
4694 fprintf(outfile,")\n");
4695 ast_print(tree->left,outfile,indent+2);
4697 /*------------------------------------------------------------------*/
4698 /*----------------------------*/
4700 /*----------------------------*/
4701 fprintf(outfile,"SUB (%p) type (",tree);
4702 printTypeChain(tree->ftype,outfile);
4703 fprintf(outfile,")\n");
4704 ast_print(tree->left,outfile,indent+2);
4705 ast_print(tree->right,outfile,indent+2);
4708 /*------------------------------------------------------------------*/
4709 /*----------------------------*/
4711 /*----------------------------*/
4713 fprintf(outfile,"COMPL (%p) type (",tree);
4714 printTypeChain(tree->ftype,outfile);
4715 fprintf(outfile,")\n");
4716 ast_print(tree->left,outfile,indent+2);
4718 /*------------------------------------------------------------------*/
4719 /*----------------------------*/
4721 /*----------------------------*/
4723 fprintf(outfile,"NOT (%p) type (",tree);
4724 printTypeChain(tree->ftype,outfile);
4725 fprintf(outfile,")\n");
4726 ast_print(tree->left,outfile,indent+2);
4728 /*------------------------------------------------------------------*/
4729 /*----------------------------*/
4731 /*----------------------------*/
4733 fprintf(outfile,"RRC (%p) type (",tree);
4734 printTypeChain(tree->ftype,outfile);
4735 fprintf(outfile,")\n");
4736 ast_print(tree->left,outfile,indent+2);
4740 fprintf(outfile,"RLC (%p) type (",tree);
4741 printTypeChain(tree->ftype,outfile);
4742 fprintf(outfile,")\n");
4743 ast_print(tree->left,outfile,indent+2);
4746 fprintf(outfile,"GETHBIT (%p) type (",tree);
4747 printTypeChain(tree->ftype,outfile);
4748 fprintf(outfile,")\n");
4749 ast_print(tree->left,outfile,indent+2);
4752 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4753 printTypeChain(tree->ftype,outfile);
4754 fprintf(outfile,")\n");
4755 ast_print(tree->left,outfile,indent+2);
4756 ast_print(tree->right,outfile,indent+2);
4759 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4760 printTypeChain(tree->ftype,outfile);
4761 fprintf(outfile,")\n");
4762 ast_print(tree->left,outfile,indent+2);
4763 ast_print(tree->right,outfile,indent+2);
4765 /*------------------------------------------------------------------*/
4766 /*----------------------------*/
4768 /*----------------------------*/
4769 case CAST: /* change the type */
4770 fprintf(outfile,"CAST (%p) from type (",tree);
4771 printTypeChain(tree->right->ftype,outfile);
4772 fprintf(outfile,") to type (");
4773 printTypeChain(tree->ftype,outfile);
4774 fprintf(outfile,")\n");
4775 ast_print(tree->right,outfile,indent+2);
4779 fprintf(outfile,"ANDAND (%p) type (",tree);
4780 printTypeChain(tree->ftype,outfile);
4781 fprintf(outfile,")\n");
4782 ast_print(tree->left,outfile,indent+2);
4783 ast_print(tree->right,outfile,indent+2);
4786 fprintf(outfile,"OROR (%p) type (",tree);
4787 printTypeChain(tree->ftype,outfile);
4788 fprintf(outfile,")\n");
4789 ast_print(tree->left,outfile,indent+2);
4790 ast_print(tree->right,outfile,indent+2);
4793 /*------------------------------------------------------------------*/
4794 /*----------------------------*/
4795 /* comparison operators */
4796 /*----------------------------*/
4798 fprintf(outfile,"GT(>) (%p) type (",tree);
4799 printTypeChain(tree->ftype,outfile);
4800 fprintf(outfile,")\n");
4801 ast_print(tree->left,outfile,indent+2);
4802 ast_print(tree->right,outfile,indent+2);
4805 fprintf(outfile,"LT(<) (%p) type (",tree);
4806 printTypeChain(tree->ftype,outfile);
4807 fprintf(outfile,")\n");
4808 ast_print(tree->left,outfile,indent+2);
4809 ast_print(tree->right,outfile,indent+2);
4812 fprintf(outfile,"LE(<=) (%p) type (",tree);
4813 printTypeChain(tree->ftype,outfile);
4814 fprintf(outfile,")\n");
4815 ast_print(tree->left,outfile,indent+2);
4816 ast_print(tree->right,outfile,indent+2);
4819 fprintf(outfile,"GE(>=) (%p) type (",tree);
4820 printTypeChain(tree->ftype,outfile);
4821 fprintf(outfile,")\n");
4822 ast_print(tree->left,outfile,indent+2);
4823 ast_print(tree->right,outfile,indent+2);
4826 fprintf(outfile,"EQ(==) (%p) type (",tree);
4827 printTypeChain(tree->ftype,outfile);
4828 fprintf(outfile,")\n");
4829 ast_print(tree->left,outfile,indent+2);
4830 ast_print(tree->right,outfile,indent+2);
4833 fprintf(outfile,"NE(!=) (%p) type (",tree);
4834 printTypeChain(tree->ftype,outfile);
4835 fprintf(outfile,")\n");
4836 ast_print(tree->left,outfile,indent+2);
4837 ast_print(tree->right,outfile,indent+2);
4838 /*------------------------------------------------------------------*/
4839 /*----------------------------*/
4841 /*----------------------------*/
4842 case SIZEOF: /* evaluate wihout code generation */
4843 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4846 /*------------------------------------------------------------------*/
4847 /*----------------------------*/
4848 /* conditional operator '?' */
4849 /*----------------------------*/
4851 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4852 printTypeChain(tree->ftype,outfile);
4853 fprintf(outfile,")\n");
4854 ast_print(tree->left,outfile,indent+2);
4855 ast_print(tree->right,outfile,indent+2);
4859 fprintf(outfile,"COLON(:) (%p) type (",tree);
4860 printTypeChain(tree->ftype,outfile);
4861 fprintf(outfile,")\n");
4862 ast_print(tree->left,outfile,indent+2);
4863 ast_print(tree->right,outfile,indent+2);
4866 /*------------------------------------------------------------------*/
4867 /*----------------------------*/
4868 /* assignment operators */
4869 /*----------------------------*/
4871 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4872 printTypeChain(tree->ftype,outfile);
4873 fprintf(outfile,")\n");
4874 ast_print(tree->left,outfile,indent+2);
4875 ast_print(tree->right,outfile,indent+2);
4878 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4879 printTypeChain(tree->ftype,outfile);
4880 fprintf(outfile,")\n");
4881 ast_print(tree->left,outfile,indent+2);
4882 ast_print(tree->right,outfile,indent+2);
4885 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4886 printTypeChain(tree->ftype,outfile);
4887 fprintf(outfile,")\n");
4888 ast_print(tree->left,outfile,indent+2);
4889 ast_print(tree->right,outfile,indent+2);
4892 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4893 printTypeChain(tree->ftype,outfile);
4894 fprintf(outfile,")\n");
4895 ast_print(tree->left,outfile,indent+2);
4896 ast_print(tree->right,outfile,indent+2);
4899 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4900 printTypeChain(tree->ftype,outfile);
4901 fprintf(outfile,")\n");
4902 ast_print(tree->left,outfile,indent+2);
4903 ast_print(tree->right,outfile,indent+2);
4906 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4907 printTypeChain(tree->ftype,outfile);
4908 fprintf(outfile,")\n");
4909 ast_print(tree->left,outfile,indent+2);
4910 ast_print(tree->right,outfile,indent+2);
4913 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4914 printTypeChain(tree->ftype,outfile);
4915 fprintf(outfile,")\n");
4916 ast_print(tree->left,outfile,indent+2);
4917 ast_print(tree->right,outfile,indent+2);
4919 /*------------------------------------------------------------------*/
4920 /*----------------------------*/
4922 /*----------------------------*/
4924 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4925 printTypeChain(tree->ftype,outfile);
4926 fprintf(outfile,")\n");
4927 ast_print(tree->left,outfile,indent+2);
4928 ast_print(tree->right,outfile,indent+2);
4930 /*------------------------------------------------------------------*/
4931 /*----------------------------*/
4933 /*----------------------------*/
4935 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4936 printTypeChain(tree->ftype,outfile);
4937 fprintf(outfile,")\n");
4938 ast_print(tree->left,outfile,indent+2);
4939 ast_print(tree->right,outfile,indent+2);
4941 /*------------------------------------------------------------------*/
4942 /*----------------------------*/
4943 /* straight assignemnt */
4944 /*----------------------------*/
4946 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4947 printTypeChain(tree->ftype,outfile);
4948 fprintf(outfile,")\n");
4949 ast_print(tree->left,outfile,indent+2);
4950 ast_print(tree->right,outfile,indent+2);
4952 /*------------------------------------------------------------------*/
4953 /*----------------------------*/
4954 /* comma operator */
4955 /*----------------------------*/
4957 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4958 printTypeChain(tree->ftype,outfile);
4959 fprintf(outfile,")\n");
4960 ast_print(tree->left,outfile,indent+2);
4961 ast_print(tree->right,outfile,indent+2);
4963 /*------------------------------------------------------------------*/
4964 /*----------------------------*/
4966 /*----------------------------*/
4969 fprintf(outfile,"CALL (%p) type (",tree);
4970 printTypeChain(tree->ftype,outfile);
4971 fprintf(outfile,")\n");
4972 ast_print(tree->left,outfile,indent+2);
4973 ast_print(tree->right,outfile,indent+2);
4976 fprintf(outfile,"PARMS\n");
4977 ast_print(tree->left,outfile,indent+2);
4978 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4979 ast_print(tree->right,outfile,indent+2);
4982 /*------------------------------------------------------------------*/
4983 /*----------------------------*/
4984 /* return statement */
4985 /*----------------------------*/
4987 fprintf(outfile,"RETURN (%p) type (",tree);
4989 printTypeChain(tree->right->ftype,outfile);
4991 fprintf(outfile,")\n");
4992 ast_print(tree->right,outfile,indent+2);
4994 /*------------------------------------------------------------------*/
4995 /*----------------------------*/
4996 /* label statement */
4997 /*----------------------------*/
4999 fprintf(outfile,"LABEL (%p)\n",tree);
5000 ast_print(tree->left,outfile,indent+2);
5001 ast_print(tree->right,outfile,indent);
5003 /*------------------------------------------------------------------*/
5004 /*----------------------------*/
5005 /* switch statement */
5006 /*----------------------------*/
5010 fprintf(outfile,"SWITCH (%p) ",tree);
5011 ast_print(tree->left,outfile,0);
5012 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5013 INDENT(indent+2,outfile);
5014 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5015 (int) floatFromVal(val),
5016 tree->values.switchVals.swNum,
5017 (int) floatFromVal(val));
5019 ast_print(tree->right,outfile,indent);
5022 /*------------------------------------------------------------------*/
5023 /*----------------------------*/
5025 /*----------------------------*/
5027 fprintf(outfile,"IF (%p) \n",tree);
5028 ast_print(tree->left,outfile,indent+2);
5029 if (tree->trueLabel) {
5030 INDENT(indent,outfile);
5031 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5033 if (tree->falseLabel) {
5034 INDENT(indent,outfile);
5035 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5037 ast_print(tree->right,outfile,indent+2);
5039 /*------------------------------------------------------------------*/
5040 /*----------------------------*/
5042 /*----------------------------*/
5044 fprintf(outfile,"FOR (%p) \n",tree);
5045 if (AST_FOR( tree, initExpr)) {
5046 INDENT(indent+2,outfile);
5047 fprintf(outfile,"INIT EXPR ");
5048 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5050 if (AST_FOR( tree, condExpr)) {
5051 INDENT(indent+2,outfile);
5052 fprintf(outfile,"COND EXPR ");
5053 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5055 if (AST_FOR( tree, loopExpr)) {
5056 INDENT(indent+2,outfile);
5057 fprintf(outfile,"LOOP EXPR ");
5058 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5060 fprintf(outfile,"FOR LOOP BODY \n");
5061 ast_print(tree->left,outfile,indent+2);
5070 ast_print(t,stdout,0);