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 */
371 /* if not block & function */
372 if (tree->type == EX_OP &&
373 (tree->opval.op != FUNCTION &&
374 tree->opval.op != BLOCK &&
375 tree->opval.op != NULLOP))
377 filename = tree->filename;
378 lineno = tree->lineno;
381 /* make sure we resolve the true & false labels for ifx */
382 if (tree->type == EX_OP && tree->opval.op == IFX)
388 if ((csym = findSym (LabelTab, tree->trueLabel,
389 tree->trueLabel->name)))
390 tree->trueLabel = csym;
392 werror (E_LABEL_UNDEF, tree->trueLabel->name);
395 if (tree->falseLabel)
397 if ((csym = findSym (LabelTab,
399 tree->falseLabel->name)))
400 tree->falseLabel = csym;
402 werror (E_LABEL_UNDEF, tree->falseLabel->name);
407 /* if this is a label resolve it from the labelTab */
408 if (IS_AST_VALUE (tree) &&
409 tree->opval.val->sym &&
410 tree->opval.val->sym->islbl)
413 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
414 tree->opval.val->sym->name);
417 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
419 tree->opval.val->sym = csym;
421 goto resolveChildren;
424 /* do only for leafs */
425 if (IS_AST_VALUE (tree) &&
426 tree->opval.val->sym &&
427 !tree->opval.val->sym->implicit)
430 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
432 /* if found in the symbol table & they r not the same */
433 if (csym && tree->opval.val->sym != csym)
435 tree->opval.val->sym = csym;
436 tree->opval.val->type = csym->type;
437 tree->opval.val->etype = csym->etype;
440 /* if not found in the symbol table */
441 /* mark it as undefined assume it is */
442 /* an integer in data space */
443 if (!csym && !tree->opval.val->sym->implicit)
446 /* if this is a function name then */
447 /* mark it as returning an int */
450 tree->opval.val->sym->type = newLink ();
451 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
452 tree->opval.val->sym->type->next =
453 tree->opval.val->sym->etype = newIntLink ();
454 tree->opval.val->etype = tree->opval.val->etype;
455 tree->opval.val->type = tree->opval.val->sym->type;
456 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
457 allocVariables (tree->opval.val->sym);
461 tree->opval.val->sym->undefined = 1;
462 tree->opval.val->type =
463 tree->opval.val->etype = newIntLink ();
464 tree->opval.val->sym->type =
465 tree->opval.val->sym->etype = newIntLink ();
471 resolveSymbols (tree->left);
472 resolveSymbols (tree->right);
477 /*-----------------------------------------------------------------*/
478 /* setAstLineno - walks a ast tree & sets the line number */
479 /*-----------------------------------------------------------------*/
480 int setAstLineno (ast * tree, int lineno)
485 tree->lineno = lineno;
486 setAstLineno (tree->left, lineno);
487 setAstLineno (tree->right, lineno);
491 /*-----------------------------------------------------------------*/
492 /* funcOfType :- function of type with name */
493 /*-----------------------------------------------------------------*/
495 funcOfType (char *name, sym_link * type, sym_link * argType,
499 /* create the symbol */
500 sym = newSymbol (name, 0);
502 /* setup return value */
503 sym->type = newLink ();
504 DCL_TYPE (sym->type) = FUNCTION;
505 sym->type->next = copyLinkChain (type);
506 sym->etype = getSpec (sym->type);
507 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
509 /* if arguments required */
513 args = FUNC_ARGS(sym->type) = newValue ();
517 args->type = copyLinkChain (argType);
518 args->etype = getSpec (args->type);
519 SPEC_EXTR(args->etype)=1;
522 args = args->next = newValue ();
529 allocVariables (sym);
534 /*-----------------------------------------------------------------*/
535 /* funcOfTypeVarg :- function of type with name and argtype */
536 /*-----------------------------------------------------------------*/
538 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
543 /* create the symbol */
544 sym = newSymbol (name, 0);
546 /* setup return value */
547 sym->type = newLink ();
548 DCL_TYPE (sym->type) = FUNCTION;
549 sym->type->next = typeFromStr(rtype);
550 sym->etype = getSpec (sym->type);
552 /* if arguments required */
555 args = FUNC_ARGS(sym->type) = newValue ();
557 for ( i = 0 ; i < nArgs ; i++ ) {
558 args->type = typeFromStr(atypes[i]);
559 args->etype = getSpec (args->type);
560 SPEC_EXTR(args->etype)=1;
561 if ((i + 1) == nArgs) break;
562 args = args->next = newValue ();
569 allocVariables (sym);
574 /*-----------------------------------------------------------------*/
575 /* reverseParms - will reverse a parameter tree */
576 /*-----------------------------------------------------------------*/
578 reverseParms (ast * ptree)
584 /* top down if we find a nonParm tree then quit */
585 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
588 ptree->left = ptree->right;
589 ptree->right = ttree;
590 reverseParms (ptree->left);
591 reverseParms (ptree->right);
597 /*-----------------------------------------------------------------*/
598 /* processParms - makes sure the parameters are okay and do some */
599 /* processing with them */
600 /*-----------------------------------------------------------------*/
602 processParms (ast * func,
605 int *parmNumber, // unused, although updated
608 /* if none of them exist */
609 if (!defParm && !actParm)
613 if (getenv("DEBUG_SANITY")) {
614 fprintf (stderr, "processParms: %s ", defParm->name);
616 /* make sure the type is complete and sane */
617 checkTypeSanity(defParm->etype, defParm->name);
620 /* if the function is being called via a pointer & */
621 /* it has not been defined a reentrant then we cannot */
622 /* have parameters */
623 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
625 werror (W_NONRENT_ARGS);
629 /* if defined parameters ended but actual parameters */
630 /* exist and this is not defined as a variable arg */
631 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
633 werror (E_TOO_MANY_PARMS);
637 /* if defined parameters present but no actual parameters */
638 if (defParm && !actParm)
640 werror (E_TOO_FEW_PARMS);
644 if (IS_VOID(actParm->ftype)) {
645 werror (E_VOID_VALUE_USED);
649 /* If this is a varargs function... */
650 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
655 if (IS_CAST_OP (actParm)
656 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
658 /* Parameter was explicitly typecast; don't touch it. */
662 ftype = actParm->ftype;
664 /* If it's a small integer, upcast to int. */
665 if (IS_INTEGRAL (ftype)
666 && (getSize (ftype) < (unsigned) INTSIZE))
668 newType = newAst_LINK(INTTYPE);
671 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
673 newType = newAst_LINK (copyLinkChain(ftype));
674 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
677 if (IS_AGGREGATE (ftype))
679 newType = newAst_LINK (copyLinkChain (ftype));
680 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
684 /* cast required; change this op to a cast. */
685 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
687 actParm->type = EX_OP;
688 actParm->opval.op = CAST;
689 actParm->left = newType;
690 actParm->right = parmCopy;
691 decorateType (actParm);
693 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
695 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
696 processParms (func, NULL, actParm->right, parmNumber, rightmost));
701 /* if defined parameters ended but actual has not & */
703 if (!defParm && actParm &&
704 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
707 resolveSymbols (actParm);
708 /* if this is a PARAM node then match left & right */
709 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
711 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
712 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
716 /* If we have found a value node by following only right-hand links,
717 * then we know that there are no more values after us.
719 * Therefore, if there are more defined parameters, the caller didn't
722 if (rightmost && defParm->next)
724 werror (E_TOO_FEW_PARMS);
729 /* the parameter type must be at least castable */
730 if (compareType (defParm->type, actParm->ftype) == 0) {
731 werror (E_INCOMPAT_TYPES);
732 printFromToType (actParm->ftype, defParm->type);
736 /* if the parameter is castable then add the cast */
737 if (compareType (defParm->type, actParm->ftype) < 0)
739 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
741 /* now change the current one to a cast */
742 actParm->type = EX_OP;
743 actParm->opval.op = CAST;
744 actParm->left = newAst_LINK (defParm->type);
745 actParm->right = pTree;
746 actParm->etype = defParm->etype;
747 actParm->ftype = defParm->type;
748 actParm->decorated=0; /* force typechecking */
749 decorateType (actParm);
752 /* make a copy and change the regparm type to the defined parm */
753 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
754 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
755 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
759 /*-----------------------------------------------------------------*/
760 /* createIvalType - generates ival for basic types */
761 /*-----------------------------------------------------------------*/
763 createIvalType (ast * sym, sym_link * type, initList * ilist)
767 /* if initList is deep */
768 if (ilist->type == INIT_DEEP)
769 ilist = ilist->init.deep;
771 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
772 return decorateType (newNode ('=', sym, iExpr));
775 /*-----------------------------------------------------------------*/
776 /* createIvalStruct - generates initial value for structures */
777 /*-----------------------------------------------------------------*/
779 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
786 sflds = SPEC_STRUCT (type)->fields;
787 if (ilist->type != INIT_DEEP)
789 werror (E_INIT_STRUCT, "");
793 iloop = ilist->init.deep;
795 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
797 /* if we have come to end */
801 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
802 lAst = decorateType (resolveSymbols (lAst));
803 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
807 werror (W_EXCESS_INITIALIZERS, "struct",
808 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
815 /*-----------------------------------------------------------------*/
816 /* createIvalArray - generates code for array initialization */
817 /*-----------------------------------------------------------------*/
819 createIvalArray (ast * sym, sym_link * type, initList * ilist)
823 int lcnt = 0, size = 0;
824 literalList *literalL;
826 /* take care of the special case */
827 /* array of characters can be init */
829 if (IS_CHAR (type->next))
830 if ((rast = createIvalCharPtr (sym,
832 decorateType (resolveSymbols (list2expr (ilist))))))
834 return decorateType (resolveSymbols (rast));
836 /* not the special case */
837 if (ilist->type != INIT_DEEP)
839 werror (E_INIT_STRUCT, "");
843 iloop = ilist->init.deep;
844 lcnt = DCL_ELEM (type);
846 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
850 aSym = decorateType (resolveSymbols(sym));
852 rast = newNode(ARRAYINIT, aSym, NULL);
853 rast->values.constlist = literalL;
855 // Make sure size is set to length of initializer list.
862 if (lcnt && size > lcnt)
864 // Array size was specified, and we have more initializers than needed.
865 char *name=sym->opval.val->sym->name;
866 int lineno=sym->opval.val->sym->lineDef;
868 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
877 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
878 aSym = decorateType (resolveSymbols (aSym));
879 rast = createIval (aSym, type->next, iloop, rast);
880 iloop = (iloop ? iloop->next : NULL);
886 /* no of elements given and we */
887 /* have generated for all of them */
890 // there has to be a better way
891 char *name=sym->opval.val->sym->name;
892 int lineno=sym->opval.val->sym->lineDef;
893 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
900 /* if we have not been given a size */
901 if (!DCL_ELEM (type))
903 DCL_ELEM (type) = size;
906 return decorateType (resolveSymbols (rast));
910 /*-----------------------------------------------------------------*/
911 /* createIvalCharPtr - generates initial values for char pointers */
912 /*-----------------------------------------------------------------*/
914 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
918 /* if this is a pointer & right is a literal array then */
919 /* just assignment will do */
920 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
921 SPEC_SCLS (iexpr->etype) == S_CODE)
922 && IS_ARRAY (iexpr->ftype)))
923 return newNode ('=', sym, iexpr);
925 /* left side is an array so we have to assign each */
927 if ((IS_LITERAL (iexpr->etype) ||
928 SPEC_SCLS (iexpr->etype) == S_CODE)
929 && IS_ARRAY (iexpr->ftype))
931 /* for each character generate an assignment */
932 /* to the array element */
933 char *s = SPEC_CVAL (iexpr->etype).v_char;
938 rast = newNode (NULLOP,
942 newAst_VALUE (valueFromLit ((float) i))),
943 newAst_VALUE (valueFromLit (*s))));
947 rast = newNode (NULLOP,
951 newAst_VALUE (valueFromLit ((float) i))),
952 newAst_VALUE (valueFromLit (*s))));
954 // now we don't need iexpr's symbol anymore
956 symbol *sym=AST_SYMBOL(iexpr);
957 memmap *segment=SPEC_OCLS(sym->etype);
958 deleteSetItem(&segment->syms, sym);
960 return decorateType (resolveSymbols (rast));
966 /*-----------------------------------------------------------------*/
967 /* createIvalPtr - generates initial value for pointers */
968 /*-----------------------------------------------------------------*/
970 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
976 if (ilist->type == INIT_DEEP)
977 ilist = ilist->init.deep;
979 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
981 /* if character pointer */
982 if (IS_CHAR (type->next))
983 if ((rast = createIvalCharPtr (sym, type, iexpr)))
986 return newNode ('=', sym, iexpr);
989 /*-----------------------------------------------------------------*/
990 /* createIval - generates code for initial value */
991 /*-----------------------------------------------------------------*/
993 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1000 /* if structure then */
1001 if (IS_STRUCT (type))
1002 rast = createIvalStruct (sym, type, ilist);
1004 /* if this is a pointer */
1006 rast = createIvalPtr (sym, type, ilist);
1008 /* if this is an array */
1009 if (IS_ARRAY (type))
1010 rast = createIvalArray (sym, type, ilist);
1012 /* if type is SPECIFIER */
1014 rast = createIvalType (sym, type, ilist);
1017 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1019 return decorateType (resolveSymbols (rast));
1022 /*-----------------------------------------------------------------*/
1023 /* initAggregates - initialises aggregate variables with initv */
1024 /*-----------------------------------------------------------------*/
1025 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1026 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1029 /*-----------------------------------------------------------------*/
1030 /* gatherAutoInit - creates assignment expressions for initial */
1032 /*-----------------------------------------------------------------*/
1034 gatherAutoInit (symbol * autoChain)
1041 for (sym = autoChain; sym; sym = sym->next)
1044 /* resolve the symbols in the ival */
1046 resolveIvalSym (sym->ival);
1048 /* if this is a static variable & has an */
1049 /* initial value the code needs to be lifted */
1050 /* here to the main portion since they can be */
1051 /* initialised only once at the start */
1052 if (IS_STATIC (sym->etype) && sym->ival &&
1053 SPEC_SCLS (sym->etype) != S_CODE)
1057 /* insert the symbol into the symbol table */
1058 /* with level = 0 & name = rname */
1059 newSym = copySymbol (sym);
1060 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1062 /* now lift the code to main */
1063 if (IS_AGGREGATE (sym->type)) {
1064 work = initAggregates (sym, sym->ival, NULL);
1066 if (getNelements(sym->type, sym->ival)>1) {
1067 werror (W_EXCESS_INITIALIZERS, "scalar",
1068 sym->name, sym->lineDef);
1070 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1071 list2expr (sym->ival));
1074 setAstLineno (work, sym->lineDef);
1078 staticAutos = newNode (NULLOP, staticAutos, work);
1085 /* if there is an initial value */
1086 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1088 if (IS_AGGREGATE (sym->type)) {
1089 work = initAggregates (sym, sym->ival, NULL);
1091 if (getNelements(sym->type, sym->ival)>1) {
1092 werror (W_EXCESS_INITIALIZERS, "scalar",
1093 sym->name, sym->lineDef);
1095 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1096 list2expr (sym->ival));
1099 setAstLineno (work, sym->lineDef);
1102 init = newNode (NULLOP, init, work);
1111 /*-----------------------------------------------------------------*/
1112 /* stringToSymbol - creates a symbol from a literal string */
1113 /*-----------------------------------------------------------------*/
1115 stringToSymbol (value * val)
1117 char name[SDCC_NAME_MAX + 1];
1118 static int charLbl = 0;
1121 sprintf (name, "_str_%d", charLbl++);
1122 sym = newSymbol (name, 0); /* make it @ level 0 */
1123 strcpy (sym->rname, name);
1125 /* copy the type from the value passed */
1126 sym->type = copyLinkChain (val->type);
1127 sym->etype = getSpec (sym->type);
1128 /* change to storage class & output class */
1129 SPEC_SCLS (sym->etype) = S_CODE;
1130 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1131 SPEC_STAT (sym->etype) = 1;
1132 /* make the level & block = 0 */
1133 sym->block = sym->level = 0;
1135 /* create an ival */
1136 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1141 allocVariables (sym);
1144 return symbolVal (sym);
1148 /*-----------------------------------------------------------------*/
1149 /* processBlockVars - will go thru the ast looking for block if */
1150 /* a block is found then will allocate the syms */
1151 /* will also gather the auto inits present */
1152 /*-----------------------------------------------------------------*/
1154 processBlockVars (ast * tree, int *stack, int action)
1159 /* if this is a block */
1160 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1164 if (action == ALLOCATE)
1166 *stack += allocVariables (tree->values.sym);
1167 autoInit = gatherAutoInit (tree->values.sym);
1169 /* if there are auto inits then do them */
1171 tree->left = newNode (NULLOP, autoInit, tree->left);
1173 else /* action is deallocate */
1174 deallocLocal (tree->values.sym);
1177 processBlockVars (tree->left, stack, action);
1178 processBlockVars (tree->right, stack, action);
1182 /*-------------------------------------------------------------*/
1183 /* constExprTree - returns TRUE if this tree is a constant */
1185 /*-------------------------------------------------------------*/
1186 bool constExprTree (ast *cexpr) {
1192 cexpr = decorateType (resolveSymbols (cexpr));
1194 switch (cexpr->type)
1197 if (IS_AST_LIT_VALUE(cexpr)) {
1198 // this is a literal
1201 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1202 // a function's address will never change
1205 if (IS_AST_SYM_VALUE(cexpr) &&
1206 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1207 // a symbol in code space will never change
1208 // This is only for the 'char *s="hallo"' case and will have to leave
1213 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1214 "unexpected link in expression tree\n");
1217 if (cexpr->opval.op==ARRAYINIT) {
1218 // this is a list of literals
1221 if (cexpr->opval.op=='=') {
1222 return constExprTree(cexpr->right);
1224 if (cexpr->opval.op==CAST) {
1225 // jwk: cast ignored, maybe we should throw a warning here
1226 return constExprTree(cexpr->right);
1228 if (cexpr->opval.op=='&') {
1231 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1234 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1241 /*-----------------------------------------------------------------*/
1242 /* constExprValue - returns the value of a constant expression */
1243 /* or NULL if it is not a constant expression */
1244 /*-----------------------------------------------------------------*/
1246 constExprValue (ast * cexpr, int check)
1248 cexpr = decorateType (resolveSymbols (cexpr));
1250 /* if this is not a constant then */
1251 if (!IS_LITERAL (cexpr->ftype))
1253 /* then check if this is a literal array
1255 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1256 SPEC_CVAL (cexpr->etype).v_char &&
1257 IS_ARRAY (cexpr->ftype))
1259 value *val = valFromType (cexpr->ftype);
1260 SPEC_SCLS (val->etype) = S_LITERAL;
1261 val->sym = cexpr->opval.val->sym;
1262 val->sym->type = copyLinkChain (cexpr->ftype);
1263 val->sym->etype = getSpec (val->sym->type);
1264 strcpy (val->name, cexpr->opval.val->sym->rname);
1268 /* if we are casting a literal value then */
1269 if (IS_AST_OP (cexpr) &&
1270 cexpr->opval.op == CAST &&
1271 IS_LITERAL (cexpr->right->ftype))
1272 return valCastLiteral (cexpr->ftype,
1273 floatFromVal (cexpr->right->opval.val));
1275 if (IS_AST_VALUE (cexpr))
1276 return cexpr->opval.val;
1279 werror (E_CONST_EXPECTED, "found expression");
1284 /* return the value */
1285 return cexpr->opval.val;
1289 /*-----------------------------------------------------------------*/
1290 /* isLabelInAst - will return true if a given label is found */
1291 /*-----------------------------------------------------------------*/
1293 isLabelInAst (symbol * label, ast * tree)
1295 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1298 if (IS_AST_OP (tree) &&
1299 tree->opval.op == LABEL &&
1300 isSymbolEqual (AST_SYMBOL (tree->left), label))
1303 return isLabelInAst (label, tree->right) &&
1304 isLabelInAst (label, tree->left);
1308 /*-----------------------------------------------------------------*/
1309 /* isLoopCountable - return true if the loop count can be determi- */
1310 /* -ned at compile time . */
1311 /*-----------------------------------------------------------------*/
1313 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1314 symbol ** sym, ast ** init, ast ** end)
1317 /* the loop is considered countable if the following
1318 conditions are true :-
1320 a) initExpr :- <sym> = <const>
1321 b) condExpr :- <sym> < <const1>
1322 c) loopExpr :- <sym> ++
1325 /* first check the initExpr */
1326 if (IS_AST_OP (initExpr) &&
1327 initExpr->opval.op == '=' && /* is assignment */
1328 IS_AST_SYM_VALUE (initExpr->left))
1329 { /* left is a symbol */
1331 *sym = AST_SYMBOL (initExpr->left);
1332 *init = initExpr->right;
1337 /* for now the symbol has to be of
1339 if (!IS_INTEGRAL ((*sym)->type))
1342 /* now check condExpr */
1343 if (IS_AST_OP (condExpr))
1346 switch (condExpr->opval.op)
1349 if (IS_AST_SYM_VALUE (condExpr->left) &&
1350 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1351 IS_AST_LIT_VALUE (condExpr->right))
1353 *end = condExpr->right;
1359 if (IS_AST_OP (condExpr->left) &&
1360 condExpr->left->opval.op == '>' &&
1361 IS_AST_LIT_VALUE (condExpr->left->right) &&
1362 IS_AST_SYM_VALUE (condExpr->left->left) &&
1363 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1366 *end = newNode ('+', condExpr->left->right,
1367 newAst_VALUE (constVal ("1")));
1378 /* check loop expression is of the form <sym>++ */
1379 if (!IS_AST_OP (loopExpr))
1382 /* check if <sym> ++ */
1383 if (loopExpr->opval.op == INC_OP)
1389 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1390 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1397 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1398 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1406 if (loopExpr->opval.op == ADD_ASSIGN)
1409 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1410 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1411 IS_AST_LIT_VALUE (loopExpr->right) &&
1412 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1420 /*-----------------------------------------------------------------*/
1421 /* astHasVolatile - returns true if ast contains any volatile */
1422 /*-----------------------------------------------------------------*/
1424 astHasVolatile (ast * tree)
1429 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1432 if (IS_AST_OP (tree))
1433 return astHasVolatile (tree->left) ||
1434 astHasVolatile (tree->right);
1439 /*-----------------------------------------------------------------*/
1440 /* astHasPointer - return true if the ast contains any ptr variable */
1441 /*-----------------------------------------------------------------*/
1443 astHasPointer (ast * tree)
1448 if (IS_AST_LINK (tree))
1451 /* if we hit an array expression then check
1452 only the left side */
1453 if (IS_AST_OP (tree) && tree->opval.op == '[')
1454 return astHasPointer (tree->left);
1456 if (IS_AST_VALUE (tree))
1457 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1459 return astHasPointer (tree->left) ||
1460 astHasPointer (tree->right);
1464 /*-----------------------------------------------------------------*/
1465 /* astHasSymbol - return true if the ast has the given symbol */
1466 /*-----------------------------------------------------------------*/
1468 astHasSymbol (ast * tree, symbol * sym)
1470 if (!tree || IS_AST_LINK (tree))
1473 if (IS_AST_VALUE (tree))
1475 if (IS_AST_SYM_VALUE (tree))
1476 return isSymbolEqual (AST_SYMBOL (tree), sym);
1481 return astHasSymbol (tree->left, sym) ||
1482 astHasSymbol (tree->right, sym);
1485 /*-----------------------------------------------------------------*/
1486 /* astHasDeref - return true if the ast has an indirect access */
1487 /*-----------------------------------------------------------------*/
1489 astHasDeref (ast * tree)
1491 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1494 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1496 return astHasDeref (tree->left) || astHasDeref (tree->right);
1499 /*-----------------------------------------------------------------*/
1500 /* isConformingBody - the loop body has to conform to a set of rules */
1501 /* for the loop to be considered reversible read on for rules */
1502 /*-----------------------------------------------------------------*/
1504 isConformingBody (ast * pbody, symbol * sym, ast * body)
1507 /* we are going to do a pre-order traversal of the
1508 tree && check for the following conditions. (essentially
1509 a set of very shallow tests )
1510 a) the sym passed does not participate in
1511 any arithmetic operation
1512 b) There are no function calls
1513 c) all jumps are within the body
1514 d) address of loop control variable not taken
1515 e) if an assignment has a pointer on the
1516 left hand side make sure right does not have
1517 loop control variable */
1519 /* if we reach the end or a leaf then true */
1520 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1523 /* if anything else is "volatile" */
1524 if (IS_VOLATILE (TETYPE (pbody)))
1527 /* we will walk the body in a pre-order traversal for
1529 switch (pbody->opval.op)
1531 /*------------------------------------------------------------------*/
1533 // if the loopvar is used as an index
1534 if (astHasSymbol(pbody->right, sym)) {
1537 return isConformingBody (pbody->right, sym, body);
1539 /*------------------------------------------------------------------*/
1544 /*------------------------------------------------------------------*/
1545 case INC_OP: /* incerement operator unary so left only */
1548 /* sure we are not sym is not modified */
1550 IS_AST_SYM_VALUE (pbody->left) &&
1551 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1555 IS_AST_SYM_VALUE (pbody->right) &&
1556 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1561 /*------------------------------------------------------------------*/
1563 case '*': /* can be unary : if right is null then unary operation */
1568 /* if right is NULL then unary operation */
1569 /*------------------------------------------------------------------*/
1570 /*----------------------------*/
1572 /*----------------------------*/
1575 if (IS_AST_SYM_VALUE (pbody->left) &&
1576 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1579 return isConformingBody (pbody->left, sym, body);
1583 if (astHasSymbol (pbody->left, sym) ||
1584 astHasSymbol (pbody->right, sym))
1589 /*------------------------------------------------------------------*/
1597 if (IS_AST_SYM_VALUE (pbody->left) &&
1598 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1601 if (IS_AST_SYM_VALUE (pbody->right) &&
1602 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1605 return isConformingBody (pbody->left, sym, body) &&
1606 isConformingBody (pbody->right, sym, body);
1613 if (IS_AST_SYM_VALUE (pbody->left) &&
1614 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1616 return isConformingBody (pbody->left, sym, body);
1618 /*------------------------------------------------------------------*/
1630 case SIZEOF: /* evaluate wihout code generation */
1632 return isConformingBody (pbody->left, sym, body) &&
1633 isConformingBody (pbody->right, sym, body);
1635 /*------------------------------------------------------------------*/
1638 /* if left has a pointer & right has loop
1639 control variable then we cannot */
1640 if (astHasPointer (pbody->left) &&
1641 astHasSymbol (pbody->right, sym))
1643 if (astHasVolatile (pbody->left))
1646 if (IS_AST_SYM_VALUE (pbody->left)) {
1647 // if the loopvar has an assignment
1648 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1650 // if the loopvar is used in another (maybe conditional) block
1651 if (astHasSymbol (pbody->right, sym) &&
1652 (pbody->level > body->level)) {
1657 if (astHasVolatile (pbody->left))
1660 if (astHasDeref(pbody->right)) return FALSE;
1662 return isConformingBody (pbody->left, sym, body) &&
1663 isConformingBody (pbody->right, sym, body);
1674 assert ("Parser should not have generated this\n");
1676 /*------------------------------------------------------------------*/
1677 /*----------------------------*/
1678 /* comma operator */
1679 /*----------------------------*/
1681 return isConformingBody (pbody->left, sym, body) &&
1682 isConformingBody (pbody->right, sym, body);
1684 /*------------------------------------------------------------------*/
1685 /*----------------------------*/
1687 /*----------------------------*/
1689 /* if local & not passed as paramater then ok */
1690 if (sym->level && !astHasSymbol(pbody->right,sym))
1694 /*------------------------------------------------------------------*/
1695 /*----------------------------*/
1696 /* return statement */
1697 /*----------------------------*/
1702 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1707 if (astHasSymbol (pbody->left, sym))
1714 return isConformingBody (pbody->left, sym, body) &&
1715 isConformingBody (pbody->right, sym, body);
1721 /*-----------------------------------------------------------------*/
1722 /* isLoopReversible - takes a for loop as input && returns true */
1723 /* if the for loop is reversible. If yes will set the value of */
1724 /* the loop control var & init value & termination value */
1725 /*-----------------------------------------------------------------*/
1727 isLoopReversible (ast * loop, symbol ** loopCntrl,
1728 ast ** init, ast ** end)
1730 /* if option says don't do it then don't */
1731 if (optimize.noLoopReverse)
1733 /* there are several tests to determine this */
1735 /* for loop has to be of the form
1736 for ( <sym> = <const1> ;
1737 [<sym> < <const2>] ;
1738 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1740 if (!isLoopCountable (AST_FOR (loop, initExpr),
1741 AST_FOR (loop, condExpr),
1742 AST_FOR (loop, loopExpr),
1743 loopCntrl, init, end))
1746 /* now do some serious checking on the body of the loop
1749 return isConformingBody (loop->left, *loopCntrl, loop->left);
1753 /*-----------------------------------------------------------------*/
1754 /* replLoopSym - replace the loop sym by loop sym -1 */
1755 /*-----------------------------------------------------------------*/
1757 replLoopSym (ast * body, symbol * sym)
1760 if (!body || IS_AST_LINK (body))
1763 if (IS_AST_SYM_VALUE (body))
1766 if (isSymbolEqual (AST_SYMBOL (body), sym))
1770 body->opval.op = '-';
1771 body->left = newAst_VALUE (symbolVal (sym));
1772 body->right = newAst_VALUE (constVal ("1"));
1780 replLoopSym (body->left, sym);
1781 replLoopSym (body->right, sym);
1785 /*-----------------------------------------------------------------*/
1786 /* reverseLoop - do the actual loop reversal */
1787 /*-----------------------------------------------------------------*/
1789 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1793 /* create the following tree
1798 if (sym) goto for_continue ;
1801 /* put it together piece by piece */
1802 rloop = newNode (NULLOP,
1803 createIf (newAst_VALUE (symbolVal (sym)),
1805 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1808 newAst_VALUE (symbolVal (sym)),
1811 replLoopSym (loop->left, sym);
1812 setAstLineno (rloop, init->lineno);
1814 rloop = newNode (NULLOP,
1816 newAst_VALUE (symbolVal (sym)),
1817 newNode ('-', end, init)),
1818 createLabel (AST_FOR (loop, continueLabel),
1822 newNode (SUB_ASSIGN,
1823 newAst_VALUE (symbolVal (sym)),
1824 newAst_VALUE (constVal ("1"))),
1827 rloop->lineno=init->lineno;
1828 return decorateType (rloop);
1832 /*-----------------------------------------------------------------*/
1833 /* decorateType - compute type for this tree also does type cheking */
1834 /* this is done bottom up, since type have to flow upwards */
1835 /* it also does constant folding, and paramater checking */
1836 /*-----------------------------------------------------------------*/
1838 decorateType (ast * tree)
1846 /* if already has type then do nothing */
1847 if (tree->decorated)
1850 tree->decorated = 1;
1852 /* print the line */
1853 /* if not block & function */
1854 if (tree->type == EX_OP &&
1855 (tree->opval.op != FUNCTION &&
1856 tree->opval.op != BLOCK &&
1857 tree->opval.op != NULLOP))
1859 filename = tree->filename;
1860 lineno = tree->lineno;
1863 /* if any child is an error | this one is an error do nothing */
1864 if (tree->isError ||
1865 (tree->left && tree->left->isError) ||
1866 (tree->right && tree->right->isError))
1869 /*------------------------------------------------------------------*/
1870 /*----------------------------*/
1871 /* leaf has been reached */
1872 /*----------------------------*/
1873 /* if this is of type value */
1874 /* just get the type */
1875 if (tree->type == EX_VALUE)
1878 if (IS_LITERAL (tree->opval.val->etype))
1881 /* if this is a character array then declare it */
1882 if (IS_ARRAY (tree->opval.val->type))
1883 tree->opval.val = stringToSymbol (tree->opval.val);
1885 /* otherwise just copy the type information */
1886 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1890 if (tree->opval.val->sym)
1892 /* if the undefined flag is set then give error message */
1893 if (tree->opval.val->sym->undefined)
1895 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1897 TTYPE (tree) = TETYPE (tree) =
1898 tree->opval.val->type = tree->opval.val->sym->type =
1899 tree->opval.val->etype = tree->opval.val->sym->etype =
1900 copyLinkChain (INTTYPE);
1905 /* if impilicit i.e. struct/union member then no type */
1906 if (tree->opval.val->sym->implicit)
1907 TTYPE (tree) = TETYPE (tree) = NULL;
1912 /* else copy the type */
1913 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1915 /* and mark it as referenced */
1916 tree->opval.val->sym->isref = 1;
1924 /* if type link for the case of cast */
1925 if (tree->type == EX_LINK)
1927 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1934 dtl = decorateType (tree->left);
1935 /* delay right side for '?' operator since conditional macro expansions might
1937 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1939 /* this is to take care of situations
1940 when the tree gets rewritten */
1941 if (dtl != tree->left)
1943 if (dtr != tree->right)
1947 /* depending on type of operator do */
1949 switch (tree->opval.op)
1951 /*------------------------------------------------------------------*/
1952 /*----------------------------*/
1954 /*----------------------------*/
1957 /* determine which is the array & which the index */
1958 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1961 ast *tempTree = tree->left;
1962 tree->left = tree->right;
1963 tree->right = tempTree;
1966 /* first check if this is a array or a pointer */
1967 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1969 werror (E_NEED_ARRAY_PTR, "[]");
1970 goto errorTreeReturn;
1973 /* check if the type of the idx */
1974 if (!IS_INTEGRAL (RTYPE (tree)))
1976 werror (E_IDX_NOT_INT);
1977 goto errorTreeReturn;
1980 /* if the left is an rvalue then error */
1983 werror (E_LVALUE_REQUIRED, "array access");
1984 goto errorTreeReturn;
1987 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1988 if (IS_PTR(LTYPE(tree))) {
1989 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1993 /*------------------------------------------------------------------*/
1994 /*----------------------------*/
1996 /*----------------------------*/
1998 /* if this is not a structure */
1999 if (!IS_STRUCT (LTYPE (tree)))
2001 werror (E_STRUCT_UNION, ".");
2002 goto errorTreeReturn;
2004 TTYPE (tree) = structElemType (LTYPE (tree),
2005 (tree->right->type == EX_VALUE ?
2006 tree->right->opval.val : NULL));
2007 TETYPE (tree) = getSpec (TTYPE (tree));
2010 /*------------------------------------------------------------------*/
2011 /*----------------------------*/
2012 /* struct/union pointer */
2013 /*----------------------------*/
2015 /* if not pointer to a structure */
2016 if (!IS_PTR (LTYPE (tree)))
2018 werror (E_PTR_REQD);
2019 goto errorTreeReturn;
2022 if (!IS_STRUCT (LTYPE (tree)->next))
2024 werror (E_STRUCT_UNION, "->");
2025 goto errorTreeReturn;
2028 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2029 (tree->right->type == EX_VALUE ?
2030 tree->right->opval.val : NULL));
2031 TETYPE (tree) = getSpec (TTYPE (tree));
2033 /* adjust the storage class */
2034 switch (DCL_TYPE(tree->left->ftype)) {
2038 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2041 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2046 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2049 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2052 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2061 /*------------------------------------------------------------------*/
2062 /*----------------------------*/
2063 /* ++/-- operation */
2064 /*----------------------------*/
2065 case INC_OP: /* incerement operator unary so left only */
2068 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2069 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2070 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2071 werror (E_CODE_WRITE, "++/--");
2080 /*------------------------------------------------------------------*/
2081 /*----------------------------*/
2083 /*----------------------------*/
2084 case '&': /* can be unary */
2085 /* if right is NULL then unary operation */
2086 if (tree->right) /* not an unary operation */
2089 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2091 werror (E_BITWISE_OP);
2092 werror (W_CONTINUE, "left & right types are ");
2093 printTypeChain (LTYPE (tree), stderr);
2094 fprintf (stderr, ",");
2095 printTypeChain (RTYPE (tree), stderr);
2096 fprintf (stderr, "\n");
2097 goto errorTreeReturn;
2100 /* if they are both literal */
2101 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2103 tree->type = EX_VALUE;
2104 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2105 valFromType (RETYPE (tree)), '&');
2107 tree->right = tree->left = NULL;
2108 TETYPE (tree) = tree->opval.val->etype;
2109 TTYPE (tree) = tree->opval.val->type;
2113 /* see if this is a GETHBIT operation if yes
2116 ast *otree = optimizeGetHbit (tree);
2119 return decorateType (otree);
2123 computeType (LTYPE (tree), RTYPE (tree));
2124 TETYPE (tree) = getSpec (TTYPE (tree));
2126 LRVAL (tree) = RRVAL (tree) = 1;
2130 /*------------------------------------------------------------------*/
2131 /*----------------------------*/
2133 /*----------------------------*/
2135 p->class = DECLARATOR;
2136 /* if bit field then error */
2137 if (IS_BITVAR (tree->left->etype))
2139 werror (E_ILLEGAL_ADDR, "address of bit variable");
2140 goto errorTreeReturn;
2143 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2145 werror (E_ILLEGAL_ADDR, "address of register variable");
2146 goto errorTreeReturn;
2149 if (IS_FUNC (LTYPE (tree)))
2151 // this ought to be ignored
2152 return (tree->left);
2153 //werror (E_ILLEGAL_ADDR, "address of function");
2154 //goto errorTreeReturn;
2157 if (IS_LITERAL(LTYPE(tree)))
2159 werror (E_ILLEGAL_ADDR, "address of literal");
2160 goto errorTreeReturn;
2165 werror (E_LVALUE_REQUIRED, "address of");
2166 goto errorTreeReturn;
2168 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2170 DCL_TYPE (p) = CPOINTER;
2171 DCL_PTR_CONST (p) = port->mem.code_ro;
2173 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2174 DCL_TYPE (p) = FPOINTER;
2175 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2176 DCL_TYPE (p) = PPOINTER;
2177 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2178 DCL_TYPE (p) = IPOINTER;
2179 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2180 DCL_TYPE (p) = EEPPOINTER;
2181 else if (SPEC_OCLS(tree->left->etype))
2182 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2184 DCL_TYPE (p) = POINTER;
2186 if (IS_AST_SYM_VALUE (tree->left))
2188 AST_SYMBOL (tree->left)->addrtaken = 1;
2189 AST_SYMBOL (tree->left)->allocreq = 1;
2192 p->next = LTYPE (tree);
2194 TETYPE (tree) = getSpec (TTYPE (tree));
2195 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2196 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2201 /*------------------------------------------------------------------*/
2202 /*----------------------------*/
2204 /*----------------------------*/
2206 /* if the rewrite succeeds then don't go any furthur */
2208 ast *wtree = optimizeRRCRLC (tree);
2210 return decorateType (wtree);
2212 /*------------------------------------------------------------------*/
2213 /*----------------------------*/
2215 /*----------------------------*/
2217 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2219 werror (E_BITWISE_OP);
2220 werror (W_CONTINUE, "left & right types are ");
2221 printTypeChain (LTYPE (tree), stderr);
2222 fprintf (stderr, ",");
2223 printTypeChain (RTYPE (tree), stderr);
2224 fprintf (stderr, "\n");
2225 goto errorTreeReturn;
2228 /* if they are both literal then */
2229 /* rewrite the tree */
2230 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2232 tree->type = EX_VALUE;
2233 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2234 valFromType (RETYPE (tree)),
2236 tree->right = tree->left = NULL;
2237 TETYPE (tree) = tree->opval.val->etype;
2238 TTYPE (tree) = tree->opval.val->type;
2241 LRVAL (tree) = RRVAL (tree) = 1;
2242 TETYPE (tree) = getSpec (TTYPE (tree) =
2243 computeType (LTYPE (tree),
2246 /*------------------------------------------------------------------*/
2247 /*----------------------------*/
2249 /*----------------------------*/
2251 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2253 werror (E_INVALID_OP, "divide");
2254 goto errorTreeReturn;
2256 /* if they are both literal then */
2257 /* rewrite the tree */
2258 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2260 tree->type = EX_VALUE;
2261 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2262 valFromType (RETYPE (tree)));
2263 tree->right = tree->left = NULL;
2264 TETYPE (tree) = getSpec (TTYPE (tree) =
2265 tree->opval.val->type);
2268 LRVAL (tree) = RRVAL (tree) = 1;
2269 TETYPE (tree) = getSpec (TTYPE (tree) =
2270 computeType (LTYPE (tree),
2274 /*------------------------------------------------------------------*/
2275 /*----------------------------*/
2277 /*----------------------------*/
2279 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2281 werror (E_BITWISE_OP);
2282 werror (W_CONTINUE, "left & right types are ");
2283 printTypeChain (LTYPE (tree), stderr);
2284 fprintf (stderr, ",");
2285 printTypeChain (RTYPE (tree), stderr);
2286 fprintf (stderr, "\n");
2287 goto errorTreeReturn;
2289 /* if they are both literal then */
2290 /* rewrite the tree */
2291 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2293 tree->type = EX_VALUE;
2294 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2295 valFromType (RETYPE (tree)));
2296 tree->right = tree->left = NULL;
2297 TETYPE (tree) = getSpec (TTYPE (tree) =
2298 tree->opval.val->type);
2301 LRVAL (tree) = RRVAL (tree) = 1;
2302 TETYPE (tree) = getSpec (TTYPE (tree) =
2303 computeType (LTYPE (tree),
2307 /*------------------------------------------------------------------*/
2308 /*----------------------------*/
2309 /* address dereference */
2310 /*----------------------------*/
2311 case '*': /* can be unary : if right is null then unary operation */
2314 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2316 werror (E_PTR_REQD);
2317 goto errorTreeReturn;
2322 werror (E_LVALUE_REQUIRED, "pointer deref");
2323 goto errorTreeReturn;
2325 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2326 LTYPE (tree)->next : NULL);
2327 TETYPE (tree) = getSpec (TTYPE (tree));
2328 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2332 /*------------------------------------------------------------------*/
2333 /*----------------------------*/
2334 /* multiplication */
2335 /*----------------------------*/
2336 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2338 werror (E_INVALID_OP, "multiplication");
2339 goto errorTreeReturn;
2342 /* if they are both literal then */
2343 /* rewrite the tree */
2344 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2346 tree->type = EX_VALUE;
2347 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2348 valFromType (RETYPE (tree)));
2349 tree->right = tree->left = NULL;
2350 TETYPE (tree) = getSpec (TTYPE (tree) =
2351 tree->opval.val->type);
2355 /* if left is a literal exchange left & right */
2356 if (IS_LITERAL (LTYPE (tree)))
2358 ast *tTree = tree->left;
2359 tree->left = tree->right;
2360 tree->right = tTree;
2363 LRVAL (tree) = RRVAL (tree) = 1;
2364 /* promote result to int if left & right are char
2365 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2366 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2367 TETYPE (tree) = getSpec (TTYPE (tree) =
2368 computeType (LTYPE (tree),
2370 SPEC_NOUN(TETYPE(tree)) = V_INT;
2372 TETYPE (tree) = getSpec (TTYPE (tree) =
2373 computeType (LTYPE (tree),
2378 /*------------------------------------------------------------------*/
2379 /*----------------------------*/
2380 /* unary '+' operator */
2381 /*----------------------------*/
2386 if (!IS_INTEGRAL (LTYPE (tree)))
2388 werror (E_UNARY_OP, '+');
2389 goto errorTreeReturn;
2392 /* if left is a literal then do it */
2393 if (IS_LITERAL (LTYPE (tree)))
2395 tree->type = EX_VALUE;
2396 tree->opval.val = valFromType (LETYPE (tree));
2398 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2402 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2406 /*------------------------------------------------------------------*/
2407 /*----------------------------*/
2409 /*----------------------------*/
2411 /* this is not a unary operation */
2412 /* if both pointers then problem */
2413 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2414 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2416 werror (E_PTR_PLUS_PTR);
2417 goto errorTreeReturn;
2420 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2421 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2423 werror (E_PLUS_INVALID, "+");
2424 goto errorTreeReturn;
2427 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2428 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2430 werror (E_PLUS_INVALID, "+");
2431 goto errorTreeReturn;
2433 /* if they are both literal then */
2434 /* rewrite the tree */
2435 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2437 tree->type = EX_VALUE;
2438 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2439 valFromType (RETYPE (tree)));
2440 tree->right = tree->left = NULL;
2441 TETYPE (tree) = getSpec (TTYPE (tree) =
2442 tree->opval.val->type);
2446 /* if the right is a pointer or left is a literal
2447 xchange left & right */
2448 if (IS_ARRAY (RTYPE (tree)) ||
2449 IS_PTR (RTYPE (tree)) ||
2450 IS_LITERAL (LTYPE (tree)))
2452 ast *tTree = tree->left;
2453 tree->left = tree->right;
2454 tree->right = tTree;
2457 LRVAL (tree) = RRVAL (tree) = 1;
2458 /* if the left is a pointer */
2459 if (IS_PTR (LTYPE (tree)))
2460 TETYPE (tree) = getSpec (TTYPE (tree) =
2463 TETYPE (tree) = getSpec (TTYPE (tree) =
2464 computeType (LTYPE (tree),
2468 /*------------------------------------------------------------------*/
2469 /*----------------------------*/
2471 /*----------------------------*/
2472 case '-': /* can be unary */
2473 /* if right is null then unary */
2477 if (!IS_ARITHMETIC (LTYPE (tree)))
2479 werror (E_UNARY_OP, tree->opval.op);
2480 goto errorTreeReturn;
2483 /* if left is a literal then do it */
2484 if (IS_LITERAL (LTYPE (tree)))
2486 tree->type = EX_VALUE;
2487 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2489 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2490 SPEC_USIGN(TETYPE(tree)) = 0;
2494 TTYPE (tree) = LTYPE (tree);
2498 /*------------------------------------------------------------------*/
2499 /*----------------------------*/
2501 /*----------------------------*/
2503 if (!(IS_PTR (LTYPE (tree)) ||
2504 IS_ARRAY (LTYPE (tree)) ||
2505 IS_ARITHMETIC (LTYPE (tree))))
2507 werror (E_PLUS_INVALID, "-");
2508 goto errorTreeReturn;
2511 if (!(IS_PTR (RTYPE (tree)) ||
2512 IS_ARRAY (RTYPE (tree)) ||
2513 IS_ARITHMETIC (RTYPE (tree))))
2515 werror (E_PLUS_INVALID, "-");
2516 goto errorTreeReturn;
2519 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2520 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2521 IS_INTEGRAL (RTYPE (tree))))
2523 werror (E_PLUS_INVALID, "-");
2524 goto errorTreeReturn;
2527 /* if they are both literal then */
2528 /* rewrite the tree */
2529 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2531 tree->type = EX_VALUE;
2532 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2533 valFromType (RETYPE (tree)));
2534 tree->right = tree->left = NULL;
2535 TETYPE (tree) = getSpec (TTYPE (tree) =
2536 tree->opval.val->type);
2540 /* if the left & right are equal then zero */
2541 if (isAstEqual (tree->left, tree->right))
2543 tree->type = EX_VALUE;
2544 tree->left = tree->right = NULL;
2545 tree->opval.val = constVal ("0");
2546 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2550 /* if both of them are pointers or arrays then */
2551 /* the result is going to be an integer */
2552 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2553 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2554 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2556 /* if only the left is a pointer */
2557 /* then result is a pointer */
2558 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2559 TETYPE (tree) = getSpec (TTYPE (tree) =
2562 TETYPE (tree) = getSpec (TTYPE (tree) =
2563 computeType (LTYPE (tree),
2565 LRVAL (tree) = RRVAL (tree) = 1;
2568 /*------------------------------------------------------------------*/
2569 /*----------------------------*/
2571 /*----------------------------*/
2573 /* can be only integral type */
2574 if (!IS_INTEGRAL (LTYPE (tree)))
2576 werror (E_UNARY_OP, tree->opval.op);
2577 goto errorTreeReturn;
2580 /* if left is a literal then do it */
2581 if (IS_LITERAL (LTYPE (tree)))
2583 tree->type = EX_VALUE;
2584 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2586 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2590 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2593 /*------------------------------------------------------------------*/
2594 /*----------------------------*/
2596 /*----------------------------*/
2598 /* can be pointer */
2599 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2600 !IS_PTR (LTYPE (tree)) &&
2601 !IS_ARRAY (LTYPE (tree)))
2603 werror (E_UNARY_OP, tree->opval.op);
2604 goto errorTreeReturn;
2607 /* if left is a literal then do it */
2608 if (IS_LITERAL (LTYPE (tree)))
2610 tree->type = EX_VALUE;
2611 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2613 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2617 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2620 /*------------------------------------------------------------------*/
2621 /*----------------------------*/
2623 /*----------------------------*/
2626 TTYPE (tree) = LTYPE (tree);
2627 TETYPE (tree) = LETYPE (tree);
2631 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2636 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2638 werror (E_SHIFT_OP_INVALID);
2639 werror (W_CONTINUE, "left & right types are ");
2640 printTypeChain (LTYPE (tree), stderr);
2641 fprintf (stderr, ",");
2642 printTypeChain (RTYPE (tree), stderr);
2643 fprintf (stderr, "\n");
2644 goto errorTreeReturn;
2647 /* if they are both literal then */
2648 /* rewrite the tree */
2649 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2651 tree->type = EX_VALUE;
2652 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2653 valFromType (RETYPE (tree)),
2654 (tree->opval.op == LEFT_OP ? 1 : 0));
2655 tree->right = tree->left = NULL;
2656 TETYPE (tree) = getSpec (TTYPE (tree) =
2657 tree->opval.val->type);
2660 /* a left shift must be done with at least 16bits */
2661 if ((tree->opval.op==LEFT_OP) && (getSize(LTYPE(tree))<2)) {
2664 decorateType (newNode (CAST,
2665 newAst_LINK(copyLinkChain(LTYPE(tree))),
2667 SPEC_NOUN(tree->left->left->ftype)=V_INT;
2669 /* if only the right side is a literal & we are
2670 shifting more than size of the left operand then zero */
2671 if (IS_LITERAL (RTYPE (tree)) &&
2672 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2673 (getSize (LTYPE (tree)) * 8))
2675 werror (W_SHIFT_CHANGED,
2676 (tree->opval.op == LEFT_OP ? "left" : "right"));
2677 tree->type = EX_VALUE;
2678 tree->left = tree->right = NULL;
2679 tree->opval.val = constVal ("0");
2680 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2683 LRVAL (tree) = RRVAL (tree) = 1;
2684 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2686 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2690 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2694 /*------------------------------------------------------------------*/
2695 /*----------------------------*/
2697 /*----------------------------*/
2698 case CAST: /* change the type */
2699 /* cannot cast to an aggregate type */
2700 if (IS_AGGREGATE (LTYPE (tree)))
2702 werror (E_CAST_ILLEGAL);
2703 goto errorTreeReturn;
2706 /* make sure the type is complete and sane */
2707 checkTypeSanity(LETYPE(tree), "(cast)");
2710 /* if the right is a literal replace the tree */
2711 if (IS_LITERAL (RETYPE (tree))) {
2712 if (!IS_PTR (LTYPE (tree))) {
2713 tree->type = EX_VALUE;
2715 valCastLiteral (LTYPE (tree),
2716 floatFromVal (valFromType (RETYPE (tree))));
2719 TTYPE (tree) = tree->opval.val->type;
2720 tree->values.literalFromCast = 1;
2721 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2722 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2723 sym_link *rest = LTYPE(tree)->next;
2724 werror(W_LITERAL_GENERIC);
2725 TTYPE(tree) = newLink();
2726 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2727 TTYPE(tree)->next = rest;
2728 tree->left->opval.lnk = TTYPE(tree);
2731 TTYPE (tree) = LTYPE (tree);
2735 TTYPE (tree) = LTYPE (tree);
2739 /* if pointer to struct then check names */
2740 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2741 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2742 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2743 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2745 /* if the right is a literal replace the tree */
2746 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2747 tree->type = EX_VALUE;
2749 valCastLiteral (LTYPE (tree),
2750 floatFromVal (valFromType (RETYPE (tree))));
2753 TTYPE (tree) = tree->opval.val->type;
2754 tree->values.literalFromCast = 1;
2756 TTYPE (tree) = LTYPE (tree);
2760 TETYPE (tree) = getSpec (TTYPE (tree));
2764 /*------------------------------------------------------------------*/
2765 /*----------------------------*/
2766 /* logical &&, || */
2767 /*----------------------------*/
2770 /* each must me arithmetic type or be a pointer */
2771 if (!IS_PTR (LTYPE (tree)) &&
2772 !IS_ARRAY (LTYPE (tree)) &&
2773 !IS_INTEGRAL (LTYPE (tree)))
2775 werror (E_COMPARE_OP);
2776 goto errorTreeReturn;
2779 if (!IS_PTR (RTYPE (tree)) &&
2780 !IS_ARRAY (RTYPE (tree)) &&
2781 !IS_INTEGRAL (RTYPE (tree)))
2783 werror (E_COMPARE_OP);
2784 goto errorTreeReturn;
2786 /* if they are both literal then */
2787 /* rewrite the tree */
2788 if (IS_LITERAL (RTYPE (tree)) &&
2789 IS_LITERAL (LTYPE (tree)))
2791 tree->type = EX_VALUE;
2792 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2793 valFromType (RETYPE (tree)),
2795 tree->right = tree->left = NULL;
2796 TETYPE (tree) = getSpec (TTYPE (tree) =
2797 tree->opval.val->type);
2800 LRVAL (tree) = RRVAL (tree) = 1;
2801 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2804 /*------------------------------------------------------------------*/
2805 /*----------------------------*/
2806 /* comparison operators */
2807 /*----------------------------*/
2815 ast *lt = optimizeCompare (tree);
2821 /* if they are pointers they must be castable */
2822 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2824 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2826 werror (E_COMPARE_OP);
2827 fprintf (stderr, "comparing type ");
2828 printTypeChain (LTYPE (tree), stderr);
2829 fprintf (stderr, "to type ");
2830 printTypeChain (RTYPE (tree), stderr);
2831 fprintf (stderr, "\n");
2832 goto errorTreeReturn;
2835 /* else they should be promotable to one another */
2838 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2839 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2841 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2843 werror (E_COMPARE_OP);
2844 fprintf (stderr, "comparing type ");
2845 printTypeChain (LTYPE (tree), stderr);
2846 fprintf (stderr, "to type ");
2847 printTypeChain (RTYPE (tree), stderr);
2848 fprintf (stderr, "\n");
2849 goto errorTreeReturn;
2852 /* if unsigned value < 0 then always false */
2853 /* if (unsigned value) > 0 then (unsigned value) */
2854 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2855 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2857 if (tree->opval.op == '<') {
2860 if (tree->opval.op == '>') {
2864 /* if they are both literal then */
2865 /* rewrite the tree */
2866 if (IS_LITERAL (RTYPE (tree)) &&
2867 IS_LITERAL (LTYPE (tree)))
2869 tree->type = EX_VALUE;
2870 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2871 valFromType (RETYPE (tree)),
2873 tree->right = tree->left = NULL;
2874 TETYPE (tree) = getSpec (TTYPE (tree) =
2875 tree->opval.val->type);
2878 LRVAL (tree) = RRVAL (tree) = 1;
2879 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2882 /*------------------------------------------------------------------*/
2883 /*----------------------------*/
2885 /*----------------------------*/
2886 case SIZEOF: /* evaluate wihout code generation */
2887 /* change the type to a integer */
2888 tree->type = EX_VALUE;
2889 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2890 tree->opval.val = constVal (buffer);
2891 tree->right = tree->left = NULL;
2892 TETYPE (tree) = getSpec (TTYPE (tree) =
2893 tree->opval.val->type);
2896 /*------------------------------------------------------------------*/
2897 /*----------------------------*/
2899 /*----------------------------*/
2901 /* return typeof enum value */
2902 tree->type = EX_VALUE;
2905 if (IS_SPEC(tree->right->ftype)) {
2906 switch (SPEC_NOUN(tree->right->ftype)) {
2908 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2909 else typeofv = TYPEOF_INT;
2912 typeofv = TYPEOF_FLOAT;
2915 typeofv = TYPEOF_CHAR;
2918 typeofv = TYPEOF_VOID;
2921 typeofv = TYPEOF_STRUCT;
2924 typeofv = TYPEOF_BIT;
2927 typeofv = TYPEOF_SBIT;
2933 switch (DCL_TYPE(tree->right->ftype)) {
2935 typeofv = TYPEOF_POINTER;
2938 typeofv = TYPEOF_FPOINTER;
2941 typeofv = TYPEOF_CPOINTER;
2944 typeofv = TYPEOF_GPOINTER;
2947 typeofv = TYPEOF_PPOINTER;
2950 typeofv = TYPEOF_IPOINTER;
2953 typeofv = TYPEOF_ARRAY;
2956 typeofv = TYPEOF_FUNCTION;
2962 sprintf (buffer, "%d", typeofv);
2963 tree->opval.val = constVal (buffer);
2964 tree->right = tree->left = NULL;
2965 TETYPE (tree) = getSpec (TTYPE (tree) =
2966 tree->opval.val->type);
2969 /*------------------------------------------------------------------*/
2970 /*----------------------------*/
2971 /* conditional operator '?' */
2972 /*----------------------------*/
2974 /* the type is value of the colon operator (on the right) */
2975 assert(IS_COLON_OP(tree->right));
2976 /* if already known then replace the tree : optimizer will do it
2977 but faster to do it here */
2978 if (IS_LITERAL (LTYPE(tree))) {
2979 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2980 return decorateType(tree->right->left) ;
2982 return decorateType(tree->right->right) ;
2985 tree->right = decorateType(tree->right);
2986 TTYPE (tree) = RTYPE(tree);
2987 TETYPE (tree) = getSpec (TTYPE (tree));
2992 /* if they don't match we have a problem */
2993 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2995 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2996 goto errorTreeReturn;
2999 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3000 TETYPE (tree) = getSpec (TTYPE (tree));
3004 #if 0 // assignment operators are converted by the parser
3005 /*------------------------------------------------------------------*/
3006 /*----------------------------*/
3007 /* assignment operators */
3008 /*----------------------------*/
3011 /* for these it must be both must be integral */
3012 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3013 !IS_ARITHMETIC (RTYPE (tree)))
3015 werror (E_OPS_INTEGRAL);
3016 goto errorTreeReturn;
3019 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3021 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3022 werror (E_CODE_WRITE, " ");
3026 werror (E_LVALUE_REQUIRED, "*= or /=");
3027 goto errorTreeReturn;
3038 /* for these it must be both must be integral */
3039 if (!IS_INTEGRAL (LTYPE (tree)) ||
3040 !IS_INTEGRAL (RTYPE (tree)))
3042 werror (E_OPS_INTEGRAL);
3043 goto errorTreeReturn;
3046 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3048 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3049 werror (E_CODE_WRITE, " ");
3053 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3054 goto errorTreeReturn;
3060 /*------------------------------------------------------------------*/
3061 /*----------------------------*/
3063 /*----------------------------*/
3065 if (!(IS_PTR (LTYPE (tree)) ||
3066 IS_ARITHMETIC (LTYPE (tree))))
3068 werror (E_PLUS_INVALID, "-=");
3069 goto errorTreeReturn;
3072 if (!(IS_PTR (RTYPE (tree)) ||
3073 IS_ARITHMETIC (RTYPE (tree))))
3075 werror (E_PLUS_INVALID, "-=");
3076 goto errorTreeReturn;
3079 TETYPE (tree) = getSpec (TTYPE (tree) =
3080 computeType (LTYPE (tree),
3083 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3084 werror (E_CODE_WRITE, " ");
3088 werror (E_LVALUE_REQUIRED, "-=");
3089 goto errorTreeReturn;
3095 /*------------------------------------------------------------------*/
3096 /*----------------------------*/
3098 /*----------------------------*/
3100 /* this is not a unary operation */
3101 /* if both pointers then problem */
3102 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3104 werror (E_PTR_PLUS_PTR);
3105 goto errorTreeReturn;
3108 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3110 werror (E_PLUS_INVALID, "+=");
3111 goto errorTreeReturn;
3114 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3116 werror (E_PLUS_INVALID, "+=");
3117 goto errorTreeReturn;
3120 TETYPE (tree) = getSpec (TTYPE (tree) =
3121 computeType (LTYPE (tree),
3124 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3125 werror (E_CODE_WRITE, " ");
3129 werror (E_LVALUE_REQUIRED, "+=");
3130 goto errorTreeReturn;
3133 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3134 tree->opval.op = '=';
3139 /*------------------------------------------------------------------*/
3140 /*----------------------------*/
3141 /* straight assignemnt */
3142 /*----------------------------*/
3144 /* cannot be an aggregate */
3145 if (IS_AGGREGATE (LTYPE (tree)))
3147 werror (E_AGGR_ASSIGN);
3148 goto errorTreeReturn;
3151 /* they should either match or be castable */
3152 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3154 werror (E_TYPE_MISMATCH, "assignment", " ");
3155 printFromToType(RTYPE(tree),LTYPE(tree));
3156 //goto errorTreeReturn;
3159 /* if the left side of the tree is of type void
3160 then report error */
3161 if (IS_VOID (LTYPE (tree)))
3163 werror (E_CAST_ZERO);
3164 printFromToType(RTYPE(tree), LTYPE(tree));
3167 TETYPE (tree) = getSpec (TTYPE (tree) =
3171 if (!tree->initMode ) {
3172 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3173 werror (E_CODE_WRITE, " ");
3177 werror (E_LVALUE_REQUIRED, "=");
3178 goto errorTreeReturn;
3183 /*------------------------------------------------------------------*/
3184 /*----------------------------*/
3185 /* comma operator */
3186 /*----------------------------*/
3188 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3191 /*------------------------------------------------------------------*/
3192 /*----------------------------*/
3194 /*----------------------------*/
3198 if (processParms (tree->left,
3199 FUNC_ARGS(tree->left->ftype),
3200 tree->right, &parmNumber, TRUE)) {
3201 goto errorTreeReturn;
3204 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3205 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3207 //FUNC_ARGS(tree->left->ftype) =
3208 //reverseVal (FUNC_ARGS(tree->left->ftype));
3209 reverseParms (tree->right);
3212 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3215 /*------------------------------------------------------------------*/
3216 /*----------------------------*/
3217 /* return statement */
3218 /*----------------------------*/
3223 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3225 werror (W_RETURN_MISMATCH);
3226 printFromToType (RTYPE(tree), currFunc->type->next);
3227 goto errorTreeReturn;
3230 if (IS_VOID (currFunc->type->next)
3232 !IS_VOID (RTYPE (tree)))
3234 werror (E_FUNC_VOID);
3235 goto errorTreeReturn;
3238 /* if there is going to be a casing required then add it */
3239 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3242 decorateType (newNode (CAST,
3243 newAst_LINK (copyLinkChain (currFunc->type->next)),
3252 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3254 werror (E_VOID_FUNC, currFunc->name);
3255 goto errorTreeReturn;
3258 TTYPE (tree) = TETYPE (tree) = NULL;
3261 /*------------------------------------------------------------------*/
3262 /*----------------------------*/
3263 /* switch statement */
3264 /*----------------------------*/
3266 /* the switch value must be an integer */
3267 if (!IS_INTEGRAL (LTYPE (tree)))
3269 werror (E_SWITCH_NON_INTEGER);
3270 goto errorTreeReturn;
3273 TTYPE (tree) = TETYPE (tree) = NULL;
3276 /*------------------------------------------------------------------*/
3277 /*----------------------------*/
3279 /*----------------------------*/
3281 tree->left = backPatchLabels (tree->left,
3284 TTYPE (tree) = TETYPE (tree) = NULL;
3287 /*------------------------------------------------------------------*/
3288 /*----------------------------*/
3290 /*----------------------------*/
3293 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3294 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3295 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3297 /* if the for loop is reversible then
3298 reverse it otherwise do what we normally
3304 if (isLoopReversible (tree, &sym, &init, &end))
3305 return reverseLoop (tree, sym, init, end);
3307 return decorateType (createFor (AST_FOR (tree, trueLabel),
3308 AST_FOR (tree, continueLabel),
3309 AST_FOR (tree, falseLabel),
3310 AST_FOR (tree, condLabel),
3311 AST_FOR (tree, initExpr),
3312 AST_FOR (tree, condExpr),
3313 AST_FOR (tree, loopExpr),
3317 TTYPE (tree) = TETYPE (tree) = NULL;
3321 /* some error found this tree will be killed */
3323 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3324 tree->opval.op = NULLOP;
3330 /*-----------------------------------------------------------------*/
3331 /* sizeofOp - processes size of operation */
3332 /*-----------------------------------------------------------------*/
3334 sizeofOp (sym_link * type)
3338 /* make sure the type is complete and sane */
3339 checkTypeSanity(type, "(sizeof)");
3341 /* get the size and convert it to character */
3342 sprintf (buff, "%d", getSize (type));
3344 /* now convert into value */
3345 return constVal (buff);
3349 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3350 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3351 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3352 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3353 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3354 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3355 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3357 /*-----------------------------------------------------------------*/
3358 /* backPatchLabels - change and or not operators to flow control */
3359 /*-----------------------------------------------------------------*/
3361 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3367 if (!(IS_ANDORNOT (tree)))
3370 /* if this an and */
3373 static int localLbl = 0;
3376 sprintf (buffer, "_and_%d", localLbl++);
3377 localLabel = newSymbol (buffer, NestLevel);
3379 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3381 /* if left is already a IFX then just change the if true label in that */
3382 if (!IS_IFX (tree->left))
3383 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3385 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3386 /* right is a IFX then just join */
3387 if (IS_IFX (tree->right))
3388 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3390 tree->right = createLabel (localLabel, tree->right);
3391 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3393 return newNode (NULLOP, tree->left, tree->right);
3396 /* if this is an or operation */
3399 static int localLbl = 0;
3402 sprintf (buffer, "_or_%d", localLbl++);
3403 localLabel = newSymbol (buffer, NestLevel);
3405 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3407 /* if left is already a IFX then just change the if true label in that */
3408 if (!IS_IFX (tree->left))
3409 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3411 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3412 /* right is a IFX then just join */
3413 if (IS_IFX (tree->right))
3414 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3416 tree->right = createLabel (localLabel, tree->right);
3417 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3419 return newNode (NULLOP, tree->left, tree->right);
3425 int wasnot = IS_NOT (tree->left);
3426 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3428 /* if the left is already a IFX */
3429 if (!IS_IFX (tree->left))
3430 tree->left = newNode (IFX, tree->left, NULL);
3434 tree->left->trueLabel = trueLabel;
3435 tree->left->falseLabel = falseLabel;
3439 tree->left->trueLabel = falseLabel;
3440 tree->left->falseLabel = trueLabel;
3447 tree->trueLabel = trueLabel;
3448 tree->falseLabel = falseLabel;
3455 /*-----------------------------------------------------------------*/
3456 /* createBlock - create expression tree for block */
3457 /*-----------------------------------------------------------------*/
3459 createBlock (symbol * decl, ast * body)
3463 /* if the block has nothing */
3467 ex = newNode (BLOCK, NULL, body);
3468 ex->values.sym = decl;
3470 ex->right = ex->right;
3476 /*-----------------------------------------------------------------*/
3477 /* createLabel - creates the expression tree for labels */
3478 /*-----------------------------------------------------------------*/
3480 createLabel (symbol * label, ast * stmnt)
3483 char name[SDCC_NAME_MAX + 1];
3486 /* must create fresh symbol if the symbol name */
3487 /* exists in the symbol table, since there can */
3488 /* be a variable with the same name as the labl */
3489 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3490 (csym->level == label->level))
3491 label = newSymbol (label->name, label->level);
3493 /* change the name before putting it in add _ */
3494 sprintf (name, "%s", label->name);
3496 /* put the label in the LabelSymbol table */
3497 /* but first check if a label of the same */
3499 if ((csym = findSym (LabelTab, NULL, name)))
3500 werror (E_DUPLICATE_LABEL, label->name);
3502 addSym (LabelTab, label, name, label->level, 0, 0);
3505 label->key = labelKey++;
3506 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3512 /*-----------------------------------------------------------------*/
3513 /* createCase - generates the parsetree for a case statement */
3514 /*-----------------------------------------------------------------*/
3516 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3518 char caseLbl[SDCC_NAME_MAX + 1];
3522 /* if the switch statement does not exist */
3523 /* then case is out of context */
3526 werror (E_CASE_CONTEXT);
3530 caseVal = decorateType (resolveSymbols (caseVal));
3531 /* if not a constant then error */
3532 if (!IS_LITERAL (caseVal->ftype))
3534 werror (E_CASE_CONSTANT);
3538 /* if not a integer than error */
3539 if (!IS_INTEGRAL (caseVal->ftype))
3541 werror (E_CASE_NON_INTEGER);
3545 /* find the end of the switch values chain */
3546 if (!(val = swStat->values.switchVals.swVals))
3547 swStat->values.switchVals.swVals = caseVal->opval.val;
3550 /* also order the cases according to value */
3552 int cVal = (int) floatFromVal (caseVal->opval.val);
3553 while (val && (int) floatFromVal (val) < cVal)
3559 /* if we reached the end then */
3562 pval->next = caseVal->opval.val;
3566 /* we found a value greater than */
3567 /* the current value we must add this */
3568 /* before the value */
3569 caseVal->opval.val->next = val;
3571 /* if this was the first in chain */
3572 if (swStat->values.switchVals.swVals == val)
3573 swStat->values.switchVals.swVals =
3576 pval->next = caseVal->opval.val;
3581 /* create the case label */
3582 sprintf (caseLbl, "_case_%d_%d",
3583 swStat->values.switchVals.swNum,
3584 (int) floatFromVal (caseVal->opval.val));
3586 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3591 /*-----------------------------------------------------------------*/
3592 /* createDefault - creates the parse tree for the default statement */
3593 /*-----------------------------------------------------------------*/
3595 createDefault (ast * swStat, ast * stmnt)
3597 char defLbl[SDCC_NAME_MAX + 1];
3599 /* if the switch statement does not exist */
3600 /* then case is out of context */
3603 werror (E_CASE_CONTEXT);
3607 /* turn on the default flag */
3608 swStat->values.switchVals.swDefault = 1;
3610 /* create the label */
3611 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3612 return createLabel (newSymbol (defLbl, 0), stmnt);
3615 /*-----------------------------------------------------------------*/
3616 /* createIf - creates the parsetree for the if statement */
3617 /*-----------------------------------------------------------------*/
3619 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3621 static int Lblnum = 0;
3623 symbol *ifTrue, *ifFalse, *ifEnd;
3625 /* if neither exists */
3626 if (!elseBody && !ifBody) {
3627 // if there are no side effects (i++, j() etc)
3628 if (!hasSEFcalls(condAst)) {
3633 /* create the labels */
3634 sprintf (buffer, "_iffalse_%d", Lblnum);
3635 ifFalse = newSymbol (buffer, NestLevel);
3636 /* if no else body then end == false */
3641 sprintf (buffer, "_ifend_%d", Lblnum);
3642 ifEnd = newSymbol (buffer, NestLevel);
3645 sprintf (buffer, "_iftrue_%d", Lblnum);
3646 ifTrue = newSymbol (buffer, NestLevel);
3650 /* attach the ifTrue label to the top of it body */
3651 ifBody = createLabel (ifTrue, ifBody);
3652 /* attach a goto end to the ifBody if else is present */
3655 ifBody = newNode (NULLOP, ifBody,
3657 newAst_VALUE (symbolVal (ifEnd)),
3659 /* put the elseLabel on the else body */
3660 elseBody = createLabel (ifFalse, elseBody);
3661 /* out the end at the end of the body */
3662 elseBody = newNode (NULLOP,
3664 createLabel (ifEnd, NULL));
3668 ifBody = newNode (NULLOP, ifBody,
3669 createLabel (ifFalse, NULL));
3671 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3672 if (IS_IFX (condAst))
3675 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3677 return newNode (NULLOP, ifTree,
3678 newNode (NULLOP, ifBody, elseBody));
3682 /*-----------------------------------------------------------------*/
3683 /* createDo - creates parse tree for do */
3686 /* _docontinue_n: */
3687 /* condition_expression +-> trueLabel -> _dobody_n */
3689 /* +-> falseLabel-> _dobreak_n */
3691 /*-----------------------------------------------------------------*/
3693 createDo (symbol * trueLabel, symbol * continueLabel,
3694 symbol * falseLabel, ast * condAst, ast * doBody)
3699 /* if the body does not exist then it is simple */
3702 condAst = backPatchLabels (condAst, continueLabel, NULL);
3703 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3704 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3705 doTree->trueLabel = continueLabel;
3706 doTree->falseLabel = NULL;
3710 /* otherwise we have a body */
3711 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3713 /* attach the body label to the top */
3714 doBody = createLabel (trueLabel, doBody);
3715 /* attach the continue label to end of body */
3716 doBody = newNode (NULLOP, doBody,
3717 createLabel (continueLabel, NULL));
3719 /* now put the break label at the end */
3720 if (IS_IFX (condAst))
3723 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3725 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3727 /* putting it together */
3728 return newNode (NULLOP, doBody, doTree);
3731 /*-----------------------------------------------------------------*/
3732 /* createFor - creates parse tree for 'for' statement */
3735 /* condExpr +-> trueLabel -> _forbody_n */
3737 /* +-> falseLabel-> _forbreak_n */
3740 /* _forcontinue_n: */
3742 /* goto _forcond_n ; */
3744 /*-----------------------------------------------------------------*/
3746 createFor (symbol * trueLabel, symbol * continueLabel,
3747 symbol * falseLabel, symbol * condLabel,
3748 ast * initExpr, ast * condExpr, ast * loopExpr,
3753 /* if loopexpression not present then we can generate it */
3754 /* the same way as a while */
3756 return newNode (NULLOP, initExpr,
3757 createWhile (trueLabel, continueLabel,
3758 falseLabel, condExpr, forBody));
3759 /* vanilla for statement */
3760 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3762 if (condExpr && !IS_IFX (condExpr))
3763 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3766 /* attach condition label to condition */
3767 condExpr = createLabel (condLabel, condExpr);
3769 /* attach body label to body */
3770 forBody = createLabel (trueLabel, forBody);
3772 /* attach continue to forLoop expression & attach */
3773 /* goto the forcond @ and of loopExpression */
3774 loopExpr = createLabel (continueLabel,
3778 newAst_VALUE (symbolVal (condLabel)),
3780 /* now start putting them together */
3781 forTree = newNode (NULLOP, initExpr, condExpr);
3782 forTree = newNode (NULLOP, forTree, forBody);
3783 forTree = newNode (NULLOP, forTree, loopExpr);
3784 /* finally add the break label */
3785 forTree = newNode (NULLOP, forTree,
3786 createLabel (falseLabel, NULL));
3790 /*-----------------------------------------------------------------*/
3791 /* createWhile - creates parse tree for while statement */
3792 /* the while statement will be created as follows */
3794 /* _while_continue_n: */
3795 /* condition_expression +-> trueLabel -> _while_boby_n */
3797 /* +-> falseLabel -> _while_break_n */
3798 /* _while_body_n: */
3800 /* goto _while_continue_n */
3801 /* _while_break_n: */
3802 /*-----------------------------------------------------------------*/
3804 createWhile (symbol * trueLabel, symbol * continueLabel,
3805 symbol * falseLabel, ast * condExpr, ast * whileBody)
3809 /* put the continue label */
3810 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3811 condExpr = createLabel (continueLabel, condExpr);
3812 condExpr->lineno = 0;
3814 /* put the body label in front of the body */
3815 whileBody = createLabel (trueLabel, whileBody);
3816 whileBody->lineno = 0;
3817 /* put a jump to continue at the end of the body */
3818 /* and put break label at the end of the body */
3819 whileBody = newNode (NULLOP,
3822 newAst_VALUE (symbolVal (continueLabel)),
3823 createLabel (falseLabel, NULL)));
3825 /* put it all together */
3826 if (IS_IFX (condExpr))
3827 whileTree = condExpr;
3830 whileTree = newNode (IFX, condExpr, NULL);
3831 /* put the true & false labels in place */
3832 whileTree->trueLabel = trueLabel;
3833 whileTree->falseLabel = falseLabel;
3836 return newNode (NULLOP, whileTree, whileBody);
3839 /*-----------------------------------------------------------------*/
3840 /* optimizeGetHbit - get highest order bit of the expression */
3841 /*-----------------------------------------------------------------*/
3843 optimizeGetHbit (ast * tree)
3846 /* if this is not a bit and */
3847 if (!IS_BITAND (tree))
3850 /* will look for tree of the form
3851 ( expr >> ((sizeof expr) -1) ) & 1 */
3852 if (!IS_AST_LIT_VALUE (tree->right))
3855 if (AST_LIT_VALUE (tree->right) != 1)
3858 if (!IS_RIGHT_OP (tree->left))
3861 if (!IS_AST_LIT_VALUE (tree->left->right))
3864 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3865 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3868 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3872 /*-----------------------------------------------------------------*/
3873 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3874 /*-----------------------------------------------------------------*/
3876 optimizeRRCRLC (ast * root)
3878 /* will look for trees of the form
3879 (?expr << 1) | (?expr >> 7) or
3880 (?expr >> 7) | (?expr << 1) will make that
3881 into a RLC : operation ..
3883 (?expr >> 1) | (?expr << 7) or
3884 (?expr << 7) | (?expr >> 1) will make that
3885 into a RRC operation
3886 note : by 7 I mean (number of bits required to hold the
3888 /* if the root operations is not a | operation the not */
3889 if (!IS_BITOR (root))
3892 /* I have to think of a better way to match patterns this sucks */
3893 /* that aside let start looking for the first case : I use a the
3894 negative check a lot to improve the efficiency */
3895 /* (?expr << 1) | (?expr >> 7) */
3896 if (IS_LEFT_OP (root->left) &&
3897 IS_RIGHT_OP (root->right))
3900 if (!SPEC_USIGN (TETYPE (root->left->left)))
3903 if (!IS_AST_LIT_VALUE (root->left->right) ||
3904 !IS_AST_LIT_VALUE (root->right->right))
3907 /* make sure it is the same expression */
3908 if (!isAstEqual (root->left->left,
3912 if (AST_LIT_VALUE (root->left->right) != 1)
3915 if (AST_LIT_VALUE (root->right->right) !=
3916 (getSize (TTYPE (root->left->left)) * 8 - 1))
3919 /* whew got the first case : create the AST */
3920 return newNode (RLC, root->left->left, NULL);
3924 /* check for second case */
3925 /* (?expr >> 7) | (?expr << 1) */
3926 if (IS_LEFT_OP (root->right) &&
3927 IS_RIGHT_OP (root->left))
3930 if (!SPEC_USIGN (TETYPE (root->left->left)))
3933 if (!IS_AST_LIT_VALUE (root->left->right) ||
3934 !IS_AST_LIT_VALUE (root->right->right))
3937 /* make sure it is the same symbol */
3938 if (!isAstEqual (root->left->left,
3942 if (AST_LIT_VALUE (root->right->right) != 1)
3945 if (AST_LIT_VALUE (root->left->right) !=
3946 (getSize (TTYPE (root->left->left)) * 8 - 1))
3949 /* whew got the first case : create the AST */
3950 return newNode (RLC, root->left->left, NULL);
3955 /* third case for RRC */
3956 /* (?symbol >> 1) | (?symbol << 7) */
3957 if (IS_LEFT_OP (root->right) &&
3958 IS_RIGHT_OP (root->left))
3961 if (!SPEC_USIGN (TETYPE (root->left->left)))
3964 if (!IS_AST_LIT_VALUE (root->left->right) ||
3965 !IS_AST_LIT_VALUE (root->right->right))
3968 /* make sure it is the same symbol */
3969 if (!isAstEqual (root->left->left,
3973 if (AST_LIT_VALUE (root->left->right) != 1)
3976 if (AST_LIT_VALUE (root->right->right) !=
3977 (getSize (TTYPE (root->left->left)) * 8 - 1))
3980 /* whew got the first case : create the AST */
3981 return newNode (RRC, root->left->left, NULL);
3985 /* fourth and last case for now */
3986 /* (?symbol << 7) | (?symbol >> 1) */
3987 if (IS_RIGHT_OP (root->right) &&
3988 IS_LEFT_OP (root->left))
3991 if (!SPEC_USIGN (TETYPE (root->left->left)))
3994 if (!IS_AST_LIT_VALUE (root->left->right) ||
3995 !IS_AST_LIT_VALUE (root->right->right))
3998 /* make sure it is the same symbol */
3999 if (!isAstEqual (root->left->left,
4003 if (AST_LIT_VALUE (root->right->right) != 1)
4006 if (AST_LIT_VALUE (root->left->right) !=
4007 (getSize (TTYPE (root->left->left)) * 8 - 1))
4010 /* whew got the first case : create the AST */
4011 return newNode (RRC, root->left->left, NULL);
4015 /* not found return root */
4019 /*-----------------------------------------------------------------*/
4020 /* optimizeCompare - otimizes compares for bit variables */
4021 /*-----------------------------------------------------------------*/
4023 optimizeCompare (ast * root)
4025 ast *optExpr = NULL;
4028 unsigned int litValue;
4030 /* if nothing then return nothing */
4034 /* if not a compare op then do leaves */
4035 if (!IS_COMPARE_OP (root))
4037 root->left = optimizeCompare (root->left);
4038 root->right = optimizeCompare (root->right);
4042 /* if left & right are the same then depending
4043 of the operation do */
4044 if (isAstEqual (root->left, root->right))
4046 switch (root->opval.op)
4051 optExpr = newAst_VALUE (constVal ("0"));
4056 optExpr = newAst_VALUE (constVal ("1"));
4060 return decorateType (optExpr);
4063 vleft = (root->left->type == EX_VALUE ?
4064 root->left->opval.val : NULL);
4066 vright = (root->right->type == EX_VALUE ?
4067 root->right->opval.val : NULL);
4069 /* if left is a BITVAR in BITSPACE */
4070 /* and right is a LITERAL then opt- */
4071 /* imize else do nothing */
4072 if (vleft && vright &&
4073 IS_BITVAR (vleft->etype) &&
4074 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4075 IS_LITERAL (vright->etype))
4078 /* if right side > 1 then comparison may never succeed */
4079 if ((litValue = (int) floatFromVal (vright)) > 1)
4081 werror (W_BAD_COMPARE);
4087 switch (root->opval.op)
4089 case '>': /* bit value greater than 1 cannot be */
4090 werror (W_BAD_COMPARE);
4094 case '<': /* bit value < 1 means 0 */
4096 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4099 case LE_OP: /* bit value <= 1 means no check */
4100 optExpr = newAst_VALUE (vright);
4103 case GE_OP: /* bit value >= 1 means only check for = */
4105 optExpr = newAst_VALUE (vleft);
4110 { /* literal is zero */
4111 switch (root->opval.op)
4113 case '<': /* bit value < 0 cannot be */
4114 werror (W_BAD_COMPARE);
4118 case '>': /* bit value > 0 means 1 */
4120 optExpr = newAst_VALUE (vleft);
4123 case LE_OP: /* bit value <= 0 means no check */
4124 case GE_OP: /* bit value >= 0 means no check */
4125 werror (W_BAD_COMPARE);
4129 case EQ_OP: /* bit == 0 means ! of bit */
4130 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4134 return decorateType (resolveSymbols (optExpr));
4135 } /* end-of-if of BITVAR */
4140 /*-----------------------------------------------------------------*/
4141 /* addSymToBlock : adds the symbol to the first block we find */
4142 /*-----------------------------------------------------------------*/
4144 addSymToBlock (symbol * sym, ast * tree)
4146 /* reached end of tree or a leaf */
4147 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4151 if (IS_AST_OP (tree) &&
4152 tree->opval.op == BLOCK)
4155 symbol *lsym = copySymbol (sym);
4157 lsym->next = AST_VALUES (tree, sym);
4158 AST_VALUES (tree, sym) = lsym;
4162 addSymToBlock (sym, tree->left);
4163 addSymToBlock (sym, tree->right);
4166 /*-----------------------------------------------------------------*/
4167 /* processRegParms - do processing for register parameters */
4168 /*-----------------------------------------------------------------*/
4170 processRegParms (value * args, ast * body)
4174 if (IS_REGPARM (args->etype))
4175 addSymToBlock (args->sym, body);
4180 /*-----------------------------------------------------------------*/
4181 /* resetParmKey - resets the operandkeys for the symbols */
4182 /*-----------------------------------------------------------------*/
4183 DEFSETFUNC (resetParmKey)
4194 /*-----------------------------------------------------------------*/
4195 /* createFunction - This is the key node that calls the iCode for */
4196 /* generating the code for a function. Note code */
4197 /* is generated function by function, later when */
4198 /* add inter-procedural analysis this will change */
4199 /*-----------------------------------------------------------------*/
4201 createFunction (symbol * name, ast * body)
4207 iCode *piCode = NULL;
4209 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4210 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4212 /* if check function return 0 then some problem */
4213 if (checkFunction (name, NULL) == 0)
4216 /* create a dummy block if none exists */
4218 body = newNode (BLOCK, NULL, NULL);
4222 /* check if the function name already in the symbol table */
4223 if ((csym = findSym (SymbolTab, NULL, name->name)))
4226 /* special case for compiler defined functions
4227 we need to add the name to the publics list : this
4228 actually means we are now compiling the compiler
4232 addSet (&publics, name);
4238 allocVariables (name);
4240 name->lastLine = yylineno;
4243 /* set the stack pointer */
4244 /* PENDING: check this for the mcs51 */
4245 stackPtr = -port->stack.direction * port->stack.call_overhead;
4246 if (IFFUNC_ISISR (name->type))
4247 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4248 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4249 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4251 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4253 fetype = getSpec (name->type); /* get the specifier for the function */
4254 /* if this is a reentrant function then */
4255 if (IFFUNC_ISREENT (name->type))
4258 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4260 /* do processing for parameters that are passed in registers */
4261 processRegParms (FUNC_ARGS(name->type), body);
4263 /* set the stack pointer */
4267 /* allocate & autoinit the block variables */
4268 processBlockVars (body, &stack, ALLOCATE);
4270 /* save the stack information */
4271 if (options.useXstack)
4272 name->xstack = SPEC_STAK (fetype) = stack;
4274 name->stack = SPEC_STAK (fetype) = stack;
4276 /* name needs to be mangled */
4277 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4279 body = resolveSymbols (body); /* resolve the symbols */
4280 body = decorateType (body); /* propagateType & do semantic checks */
4282 ex = newAst_VALUE (symbolVal (name)); /* create name */
4283 ex = newNode (FUNCTION, ex, body);
4284 ex->values.args = FUNC_ARGS(name->type);
4286 if (options.dump_tree) PA(ex);
4289 werror (E_FUNC_NO_CODE, name->name);
4293 /* create the node & generate intermediate code */
4295 codeOutFile = code->oFile;
4296 piCode = iCodeFromAst (ex);
4300 werror (E_FUNC_NO_CODE, name->name);
4304 eBBlockFromiCode (piCode);
4306 /* if there are any statics then do them */
4309 GcurMemmap = statsg;
4310 codeOutFile = statsg->oFile;
4311 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4317 /* dealloc the block variables */
4318 processBlockVars (body, &stack, DEALLOCATE);
4319 /* deallocate paramaters */
4320 deallocParms (FUNC_ARGS(name->type));
4322 if (IFFUNC_ISREENT (name->type))
4325 /* we are done freeup memory & cleanup */
4327 if (port->reset_labelKey) labelKey = 1;
4329 FUNC_HASBODY(name->type) = 1;
4330 addSet (&operKeyReset, name);
4331 applyToSet (operKeyReset, resetParmKey);
4334 cdbStructBlock (1, cdbFile);
4336 cleanUpLevel (LabelTab, 0);
4337 cleanUpBlock (StructTab, 1);
4338 cleanUpBlock (TypedefTab, 1);
4340 xstack->syms = NULL;
4341 istack->syms = NULL;
4346 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4347 /*-----------------------------------------------------------------*/
4348 /* ast_print : prints the ast (for debugging purposes) */
4349 /*-----------------------------------------------------------------*/
4351 void ast_print (ast * tree, FILE *outfile, int indent)
4356 /* can print only decorated trees */
4357 if (!tree->decorated) return;
4359 /* if any child is an error | this one is an error do nothing */
4360 if (tree->isError ||
4361 (tree->left && tree->left->isError) ||
4362 (tree->right && tree->right->isError)) {
4363 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4367 /* print the line */
4368 /* if not block & function */
4369 if (tree->type == EX_OP &&
4370 (tree->opval.op != FUNCTION &&
4371 tree->opval.op != BLOCK &&
4372 tree->opval.op != NULLOP)) {
4375 if (tree->opval.op == FUNCTION) {
4377 value *args=FUNC_ARGS(tree->left->opval.val->type);
4378 fprintf(outfile,"FUNCTION (%s=%p) type (",
4379 tree->left->opval.val->name, tree);
4380 printTypeChain (tree->ftype,outfile);
4381 fprintf(outfile,") args (");
4384 fprintf (outfile, ", ");
4386 printTypeChain (args ? args->type : NULL, outfile);
4388 args= args ? args->next : NULL;
4390 fprintf(outfile,")\n");
4391 ast_print(tree->left,outfile,indent);
4392 ast_print(tree->right,outfile,indent);
4395 if (tree->opval.op == BLOCK) {
4396 symbol *decls = tree->values.sym;
4397 INDENT(indent,outfile);
4398 fprintf(outfile,"{\n");
4400 INDENT(indent+2,outfile);
4401 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4402 decls->name, decls);
4403 printTypeChain(decls->type,outfile);
4404 fprintf(outfile,")\n");
4406 decls = decls->next;
4408 ast_print(tree->right,outfile,indent+2);
4409 INDENT(indent,outfile);
4410 fprintf(outfile,"}\n");
4413 if (tree->opval.op == NULLOP) {
4414 fprintf(outfile,"\n");
4415 ast_print(tree->left,outfile,indent);
4416 fprintf(outfile,"\n");
4417 ast_print(tree->right,outfile,indent);
4420 INDENT(indent,outfile);
4422 /*------------------------------------------------------------------*/
4423 /*----------------------------*/
4424 /* leaf has been reached */
4425 /*----------------------------*/
4426 /* if this is of type value */
4427 /* just get the type */
4428 if (tree->type == EX_VALUE) {
4430 if (IS_LITERAL (tree->opval.val->etype)) {
4431 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4432 (int) floatFromVal(tree->opval.val),
4433 (int) floatFromVal(tree->opval.val),
4434 floatFromVal(tree->opval.val));
4435 } else if (tree->opval.val->sym) {
4436 /* if the undefined flag is set then give error message */
4437 if (tree->opval.val->sym->undefined) {
4438 fprintf(outfile,"UNDEFINED SYMBOL ");
4440 fprintf(outfile,"SYMBOL ");
4442 fprintf(outfile,"(%s=%p)",
4443 tree->opval.val->sym->name,tree);
4446 fprintf(outfile," type (");
4447 printTypeChain(tree->ftype,outfile);
4448 fprintf(outfile,")\n");
4450 fprintf(outfile,"\n");
4455 /* if type link for the case of cast */
4456 if (tree->type == EX_LINK) {
4457 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4458 printTypeChain(tree->opval.lnk,outfile);
4459 fprintf(outfile,")\n");
4464 /* depending on type of operator do */
4466 switch (tree->opval.op) {
4467 /*------------------------------------------------------------------*/
4468 /*----------------------------*/
4470 /*----------------------------*/
4472 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4473 printTypeChain(tree->ftype,outfile);
4474 fprintf(outfile,")\n");
4475 ast_print(tree->left,outfile,indent+2);
4476 ast_print(tree->right,outfile,indent+2);
4479 /*------------------------------------------------------------------*/
4480 /*----------------------------*/
4482 /*----------------------------*/
4484 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4485 printTypeChain(tree->ftype,outfile);
4486 fprintf(outfile,")\n");
4487 ast_print(tree->left,outfile,indent+2);
4488 ast_print(tree->right,outfile,indent+2);
4491 /*------------------------------------------------------------------*/
4492 /*----------------------------*/
4493 /* struct/union pointer */
4494 /*----------------------------*/
4496 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4497 printTypeChain(tree->ftype,outfile);
4498 fprintf(outfile,")\n");
4499 ast_print(tree->left,outfile,indent+2);
4500 ast_print(tree->right,outfile,indent+2);
4503 /*------------------------------------------------------------------*/
4504 /*----------------------------*/
4505 /* ++/-- operation */
4506 /*----------------------------*/
4507 case INC_OP: /* incerement operator unary so left only */
4508 fprintf(outfile,"INC_OP (%p) type (",tree);
4509 printTypeChain(tree->ftype,outfile);
4510 fprintf(outfile,")\n");
4511 ast_print(tree->left,outfile,indent+2);
4515 fprintf(outfile,"DEC_OP (%p) type (",tree);
4516 printTypeChain(tree->ftype,outfile);
4517 fprintf(outfile,")\n");
4518 ast_print(tree->left,outfile,indent+2);
4521 /*------------------------------------------------------------------*/
4522 /*----------------------------*/
4524 /*----------------------------*/
4527 fprintf(outfile,"& (%p) type (",tree);
4528 printTypeChain(tree->ftype,outfile);
4529 fprintf(outfile,")\n");
4530 ast_print(tree->left,outfile,indent+2);
4531 ast_print(tree->right,outfile,indent+2);
4533 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4534 printTypeChain(tree->ftype,outfile);
4535 fprintf(outfile,")\n");
4536 ast_print(tree->left,outfile,indent+2);
4537 ast_print(tree->right,outfile,indent+2);
4540 /*----------------------------*/
4542 /*----------------------------*/
4544 fprintf(outfile,"OR (%p) type (",tree);
4545 printTypeChain(tree->ftype,outfile);
4546 fprintf(outfile,")\n");
4547 ast_print(tree->left,outfile,indent+2);
4548 ast_print(tree->right,outfile,indent+2);
4550 /*------------------------------------------------------------------*/
4551 /*----------------------------*/
4553 /*----------------------------*/
4555 fprintf(outfile,"XOR (%p) type (",tree);
4556 printTypeChain(tree->ftype,outfile);
4557 fprintf(outfile,")\n");
4558 ast_print(tree->left,outfile,indent+2);
4559 ast_print(tree->right,outfile,indent+2);
4562 /*------------------------------------------------------------------*/
4563 /*----------------------------*/
4565 /*----------------------------*/
4567 fprintf(outfile,"DIV (%p) type (",tree);
4568 printTypeChain(tree->ftype,outfile);
4569 fprintf(outfile,")\n");
4570 ast_print(tree->left,outfile,indent+2);
4571 ast_print(tree->right,outfile,indent+2);
4573 /*------------------------------------------------------------------*/
4574 /*----------------------------*/
4576 /*----------------------------*/
4578 fprintf(outfile,"MOD (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+2);
4582 ast_print(tree->right,outfile,indent+2);
4585 /*------------------------------------------------------------------*/
4586 /*----------------------------*/
4587 /* address dereference */
4588 /*----------------------------*/
4589 case '*': /* can be unary : if right is null then unary operation */
4591 fprintf(outfile,"DEREF (%p) type (",tree);
4592 printTypeChain(tree->ftype,outfile);
4593 fprintf(outfile,")\n");
4594 ast_print(tree->left,outfile,indent+2);
4597 /*------------------------------------------------------------------*/
4598 /*----------------------------*/
4599 /* multiplication */
4600 /*----------------------------*/
4601 fprintf(outfile,"MULT (%p) type (",tree);
4602 printTypeChain(tree->ftype,outfile);
4603 fprintf(outfile,")\n");
4604 ast_print(tree->left,outfile,indent+2);
4605 ast_print(tree->right,outfile,indent+2);
4609 /*------------------------------------------------------------------*/
4610 /*----------------------------*/
4611 /* unary '+' operator */
4612 /*----------------------------*/
4616 fprintf(outfile,"UPLUS (%p) type (",tree);
4617 printTypeChain(tree->ftype,outfile);
4618 fprintf(outfile,")\n");
4619 ast_print(tree->left,outfile,indent+2);
4621 /*------------------------------------------------------------------*/
4622 /*----------------------------*/
4624 /*----------------------------*/
4625 fprintf(outfile,"ADD (%p) type (",tree);
4626 printTypeChain(tree->ftype,outfile);
4627 fprintf(outfile,")\n");
4628 ast_print(tree->left,outfile,indent+2);
4629 ast_print(tree->right,outfile,indent+2);
4632 /*------------------------------------------------------------------*/
4633 /*----------------------------*/
4635 /*----------------------------*/
4636 case '-': /* can be unary */
4638 fprintf(outfile,"UMINUS (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+2);
4643 /*------------------------------------------------------------------*/
4644 /*----------------------------*/
4646 /*----------------------------*/
4647 fprintf(outfile,"SUB (%p) type (",tree);
4648 printTypeChain(tree->ftype,outfile);
4649 fprintf(outfile,")\n");
4650 ast_print(tree->left,outfile,indent+2);
4651 ast_print(tree->right,outfile,indent+2);
4654 /*------------------------------------------------------------------*/
4655 /*----------------------------*/
4657 /*----------------------------*/
4659 fprintf(outfile,"COMPL (%p) type (",tree);
4660 printTypeChain(tree->ftype,outfile);
4661 fprintf(outfile,")\n");
4662 ast_print(tree->left,outfile,indent+2);
4664 /*------------------------------------------------------------------*/
4665 /*----------------------------*/
4667 /*----------------------------*/
4669 fprintf(outfile,"NOT (%p) type (",tree);
4670 printTypeChain(tree->ftype,outfile);
4671 fprintf(outfile,")\n");
4672 ast_print(tree->left,outfile,indent+2);
4674 /*------------------------------------------------------------------*/
4675 /*----------------------------*/
4677 /*----------------------------*/
4679 fprintf(outfile,"RRC (%p) type (",tree);
4680 printTypeChain(tree->ftype,outfile);
4681 fprintf(outfile,")\n");
4682 ast_print(tree->left,outfile,indent+2);
4686 fprintf(outfile,"RLC (%p) type (",tree);
4687 printTypeChain(tree->ftype,outfile);
4688 fprintf(outfile,")\n");
4689 ast_print(tree->left,outfile,indent+2);
4692 fprintf(outfile,"GETHBIT (%p) type (",tree);
4693 printTypeChain(tree->ftype,outfile);
4694 fprintf(outfile,")\n");
4695 ast_print(tree->left,outfile,indent+2);
4698 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4699 printTypeChain(tree->ftype,outfile);
4700 fprintf(outfile,")\n");
4701 ast_print(tree->left,outfile,indent+2);
4702 ast_print(tree->right,outfile,indent+2);
4705 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4706 printTypeChain(tree->ftype,outfile);
4707 fprintf(outfile,")\n");
4708 ast_print(tree->left,outfile,indent+2);
4709 ast_print(tree->right,outfile,indent+2);
4711 /*------------------------------------------------------------------*/
4712 /*----------------------------*/
4714 /*----------------------------*/
4715 case CAST: /* change the type */
4716 fprintf(outfile,"CAST (%p) from type (",tree);
4717 printTypeChain(tree->right->ftype,outfile);
4718 fprintf(outfile,") to type (");
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->right,outfile,indent+2);
4725 fprintf(outfile,"ANDAND (%p) type (",tree);
4726 printTypeChain(tree->ftype,outfile);
4727 fprintf(outfile,")\n");
4728 ast_print(tree->left,outfile,indent+2);
4729 ast_print(tree->right,outfile,indent+2);
4732 fprintf(outfile,"OROR (%p) type (",tree);
4733 printTypeChain(tree->ftype,outfile);
4734 fprintf(outfile,")\n");
4735 ast_print(tree->left,outfile,indent+2);
4736 ast_print(tree->right,outfile,indent+2);
4739 /*------------------------------------------------------------------*/
4740 /*----------------------------*/
4741 /* comparison operators */
4742 /*----------------------------*/
4744 fprintf(outfile,"GT(>) (%p) type (",tree);
4745 printTypeChain(tree->ftype,outfile);
4746 fprintf(outfile,")\n");
4747 ast_print(tree->left,outfile,indent+2);
4748 ast_print(tree->right,outfile,indent+2);
4751 fprintf(outfile,"LT(<) (%p) type (",tree);
4752 printTypeChain(tree->ftype,outfile);
4753 fprintf(outfile,")\n");
4754 ast_print(tree->left,outfile,indent+2);
4755 ast_print(tree->right,outfile,indent+2);
4758 fprintf(outfile,"LE(<=) (%p) type (",tree);
4759 printTypeChain(tree->ftype,outfile);
4760 fprintf(outfile,")\n");
4761 ast_print(tree->left,outfile,indent+2);
4762 ast_print(tree->right,outfile,indent+2);
4765 fprintf(outfile,"GE(>=) (%p) type (",tree);
4766 printTypeChain(tree->ftype,outfile);
4767 fprintf(outfile,")\n");
4768 ast_print(tree->left,outfile,indent+2);
4769 ast_print(tree->right,outfile,indent+2);
4772 fprintf(outfile,"EQ(==) (%p) type (",tree);
4773 printTypeChain(tree->ftype,outfile);
4774 fprintf(outfile,")\n");
4775 ast_print(tree->left,outfile,indent+2);
4776 ast_print(tree->right,outfile,indent+2);
4779 fprintf(outfile,"NE(!=) (%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);
4784 /*------------------------------------------------------------------*/
4785 /*----------------------------*/
4787 /*----------------------------*/
4788 case SIZEOF: /* evaluate wihout code generation */
4789 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4792 /*------------------------------------------------------------------*/
4793 /*----------------------------*/
4794 /* conditional operator '?' */
4795 /*----------------------------*/
4797 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4798 printTypeChain(tree->ftype,outfile);
4799 fprintf(outfile,")\n");
4800 ast_print(tree->left,outfile,indent+2);
4801 ast_print(tree->right,outfile,indent+2);
4805 fprintf(outfile,"COLON(:) (%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 /*------------------------------------------------------------------*/
4813 /*----------------------------*/
4814 /* assignment operators */
4815 /*----------------------------*/
4817 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4818 printTypeChain(tree->ftype,outfile);
4819 fprintf(outfile,")\n");
4820 ast_print(tree->left,outfile,indent+2);
4821 ast_print(tree->right,outfile,indent+2);
4824 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4825 printTypeChain(tree->ftype,outfile);
4826 fprintf(outfile,")\n");
4827 ast_print(tree->left,outfile,indent+2);
4828 ast_print(tree->right,outfile,indent+2);
4831 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4832 printTypeChain(tree->ftype,outfile);
4833 fprintf(outfile,")\n");
4834 ast_print(tree->left,outfile,indent+2);
4835 ast_print(tree->right,outfile,indent+2);
4838 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4839 printTypeChain(tree->ftype,outfile);
4840 fprintf(outfile,")\n");
4841 ast_print(tree->left,outfile,indent+2);
4842 ast_print(tree->right,outfile,indent+2);
4845 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4846 printTypeChain(tree->ftype,outfile);
4847 fprintf(outfile,")\n");
4848 ast_print(tree->left,outfile,indent+2);
4849 ast_print(tree->right,outfile,indent+2);
4852 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4853 printTypeChain(tree->ftype,outfile);
4854 fprintf(outfile,")\n");
4855 ast_print(tree->left,outfile,indent+2);
4856 ast_print(tree->right,outfile,indent+2);
4859 fprintf(outfile,"LSHFTASS(*=) (%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);
4865 /*------------------------------------------------------------------*/
4866 /*----------------------------*/
4868 /*----------------------------*/
4870 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4871 printTypeChain(tree->ftype,outfile);
4872 fprintf(outfile,")\n");
4873 ast_print(tree->left,outfile,indent+2);
4874 ast_print(tree->right,outfile,indent+2);
4876 /*------------------------------------------------------------------*/
4877 /*----------------------------*/
4879 /*----------------------------*/
4881 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4882 printTypeChain(tree->ftype,outfile);
4883 fprintf(outfile,")\n");
4884 ast_print(tree->left,outfile,indent+2);
4885 ast_print(tree->right,outfile,indent+2);
4887 /*------------------------------------------------------------------*/
4888 /*----------------------------*/
4889 /* straight assignemnt */
4890 /*----------------------------*/
4892 fprintf(outfile,"ASSIGN(=) (%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);
4898 /*------------------------------------------------------------------*/
4899 /*----------------------------*/
4900 /* comma operator */
4901 /*----------------------------*/
4903 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4904 printTypeChain(tree->ftype,outfile);
4905 fprintf(outfile,")\n");
4906 ast_print(tree->left,outfile,indent+2);
4907 ast_print(tree->right,outfile,indent+2);
4909 /*------------------------------------------------------------------*/
4910 /*----------------------------*/
4912 /*----------------------------*/
4915 fprintf(outfile,"CALL (%p) type (",tree);
4916 printTypeChain(tree->ftype,outfile);
4917 fprintf(outfile,")\n");
4918 ast_print(tree->left,outfile,indent+2);
4919 ast_print(tree->right,outfile,indent+2);
4922 fprintf(outfile,"PARMS\n");
4923 ast_print(tree->left,outfile,indent+2);
4924 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4925 ast_print(tree->right,outfile,indent+2);
4928 /*------------------------------------------------------------------*/
4929 /*----------------------------*/
4930 /* return statement */
4931 /*----------------------------*/
4933 fprintf(outfile,"RETURN (%p) type (",tree);
4935 printTypeChain(tree->right->ftype,outfile);
4937 fprintf(outfile,")\n");
4938 ast_print(tree->right,outfile,indent+2);
4940 /*------------------------------------------------------------------*/
4941 /*----------------------------*/
4942 /* label statement */
4943 /*----------------------------*/
4945 fprintf(outfile,"LABEL (%p)\n",tree);
4946 ast_print(tree->left,outfile,indent+2);
4947 ast_print(tree->right,outfile,indent);
4949 /*------------------------------------------------------------------*/
4950 /*----------------------------*/
4951 /* switch statement */
4952 /*----------------------------*/
4956 fprintf(outfile,"SWITCH (%p) ",tree);
4957 ast_print(tree->left,outfile,0);
4958 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4959 INDENT(indent+2,outfile);
4960 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4961 (int) floatFromVal(val),
4962 tree->values.switchVals.swNum,
4963 (int) floatFromVal(val));
4965 ast_print(tree->right,outfile,indent);
4968 /*------------------------------------------------------------------*/
4969 /*----------------------------*/
4971 /*----------------------------*/
4973 fprintf(outfile,"IF (%p) \n",tree);
4974 ast_print(tree->left,outfile,indent+2);
4975 if (tree->trueLabel) {
4976 INDENT(indent,outfile);
4977 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4979 if (tree->falseLabel) {
4980 INDENT(indent,outfile);
4981 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4983 ast_print(tree->right,outfile,indent+2);
4985 /*------------------------------------------------------------------*/
4986 /*----------------------------*/
4988 /*----------------------------*/
4990 fprintf(outfile,"FOR (%p) \n",tree);
4991 if (AST_FOR( tree, initExpr)) {
4992 INDENT(indent+2,outfile);
4993 fprintf(outfile,"INIT EXPR ");
4994 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4996 if (AST_FOR( tree, condExpr)) {
4997 INDENT(indent+2,outfile);
4998 fprintf(outfile,"COND EXPR ");
4999 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5001 if (AST_FOR( tree, loopExpr)) {
5002 INDENT(indent+2,outfile);
5003 fprintf(outfile,"LOOP EXPR ");
5004 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5006 fprintf(outfile,"FOR LOOP BODY \n");
5007 ast_print(tree->left,outfile,indent+2);
5016 ast_print(t,stdout,0);