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 -------------------------------------------------------------------------*/
30 set *operKeyReset = NULL;
31 ast *staticAutos = NULL;
34 #define LRVAL(x) x->left->rvalue
35 #define RRVAL(x) x->right->rvalue
36 #define TRVAL(x) x->rvalue
37 #define LLVAL(x) x->left->lvalue
38 #define RLVAL(x) x->right->lvalue
39 #define TLVAL(x) x->lvalue
40 #define RTYPE(x) x->right->ftype
41 #define RETYPE(x) x->right->etype
42 #define LTYPE(x) x->left->ftype
43 #define LETYPE(x) x->left->etype
44 #define TTYPE(x) x->ftype
45 #define TETYPE(x) x->etype
53 ast *createIval (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC (ast *);
56 ast *optimizeGetHbit (ast *);
57 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 /*-----------------------------------------------------------------*/
74 newAst (int type, void *op)
77 static int oldLineno = 0;
79 Safe_calloc (1, ex, sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : yylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
88 /* depending on the type */
92 ex->opval.val = (value *) op;
95 ex->opval.op = (long) op;
98 ex->opval.lnk = (sym_link *) op;
101 ex->opval.stmnt = (unsigned) op;
109 newAst_ (unsigned type)
112 static int oldLineno = 0;
114 ex = Safe_calloc (1, sizeof (ast));
117 ex->lineno = (noLineno ? oldLineno : yylineno);
118 ex->filename = currFname;
119 ex->level = NestLevel;
120 ex->block = currBlockno;
121 ex->initMode = inInitMode;
126 newAst_VALUE (value * val)
128 ast *ex = newAst_ (EX_VALUE);
134 newAst_OP (unsigned op)
136 ast *ex = newAst_ (EX_OP);
142 newAst_LINK (sym_link * val)
144 ast *ex = newAst_ (EX_LINK);
150 newAst_STMNT (unsigned val)
152 ast *ex = newAst_ (EX_STMNT);
153 ex->opval.stmnt = val;
157 /*-----------------------------------------------------------------*/
158 /* newNode - creates a new node */
159 /*-----------------------------------------------------------------*/
161 newNode (long op, ast * left, ast * right)
172 /*-----------------------------------------------------------------*/
173 /* newIfxNode - creates a new Ifx Node */
174 /*-----------------------------------------------------------------*/
176 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
180 /* if this is a literal then we already know the result */
181 if (condAst->etype && IS_LITERAL (condAst->etype))
184 /* then depending on the expression value */
185 if (floatFromVal (condAst->opval.val))
186 ifxNode = newNode (GOTO,
187 newAst_VALUE (symbolVal (trueLabel)),
190 ifxNode = newNode (GOTO,
191 newAst_VALUE (symbolVal (falseLabel)),
196 ifxNode = newNode (IFX, condAst, NULL);
197 ifxNode->trueLabel = trueLabel;
198 ifxNode->falseLabel = falseLabel;
204 /*-----------------------------------------------------------------*/
205 /* copyAstValues - copies value portion of ast if needed */
206 /*-----------------------------------------------------------------*/
208 copyAstValues (ast * dest, ast * src)
210 switch (src->opval.op)
213 dest->values.sym = copySymbolChain (src->values.sym);
217 dest->values.switchVals.swVals =
218 copyValue (src->values.switchVals.swVals);
219 dest->values.switchVals.swDefault =
220 src->values.switchVals.swDefault;
221 dest->values.switchVals.swNum =
222 src->values.switchVals.swNum;
226 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
227 strcpy (dest->values.inlineasm, src->values.inlineasm);
230 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
231 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
232 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
233 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
234 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
235 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
236 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
241 /*-----------------------------------------------------------------*/
242 /* copyAst - makes a copy of a given astession */
243 /*-----------------------------------------------------------------*/
252 dest = Safe_calloc (1, sizeof (ast));
254 dest->type = src->type;
255 dest->lineno = src->lineno;
256 dest->level = src->level;
257 dest->funcName = src->funcName;
258 dest->argSym = src->argSym;
260 /* if this is a leaf */
262 if (src->type == EX_VALUE)
264 dest->opval.val = copyValue (src->opval.val);
269 if (src->type == EX_LINK)
271 dest->opval.lnk = copyLinkChain (src->opval.lnk);
275 dest->opval.op = src->opval.op;
277 /* if this is a node that has special values */
278 copyAstValues (dest, src);
281 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
283 dest->trueLabel = copySymbol (src->trueLabel);
284 dest->falseLabel = copySymbol (src->falseLabel);
285 dest->left = copyAst (src->left);
286 dest->right = copyAst (src->right);
292 /*-----------------------------------------------------------------*/
293 /* hasSEFcalls - returns TRUE if tree has a function call */
294 /*-----------------------------------------------------------------*/
296 hasSEFcalls (ast * tree)
301 if (tree->type == EX_OP &&
302 (tree->opval.op == CALL ||
303 tree->opval.op == PCALL ||
304 tree->opval.op == '=' ||
305 tree->opval.op == INC_OP ||
306 tree->opval.op == DEC_OP))
309 return (hasSEFcalls (tree->left) |
310 hasSEFcalls (tree->right));
313 /*-----------------------------------------------------------------*/
314 /* isAstEqual - compares two asts & returns 1 if they are equal */
315 /*-----------------------------------------------------------------*/
317 isAstEqual (ast * t1, ast * t2)
326 if (t1->type != t2->type)
332 if (t1->opval.op != t2->opval.op)
334 return (isAstEqual (t1->left, t2->left) &&
335 isAstEqual (t1->right, t2->right));
339 if (t1->opval.val->sym)
341 if (!t2->opval.val->sym)
344 return isSymbolEqual (t1->opval.val->sym,
349 if (t2->opval.val->sym)
352 return (floatFromVal (t1->opval.val) ==
353 floatFromVal (t2->opval.val));
357 /* only compare these two types */
365 /*-----------------------------------------------------------------*/
366 /* resolveSymbols - resolve symbols from the symbol table */
367 /*-----------------------------------------------------------------*/
369 resolveSymbols (ast * tree)
371 /* walk the entire tree and check for values */
372 /* with symbols if we find one then replace */
373 /* symbol with that from the symbol table */
379 /* if not block & function */
380 if (tree->type == EX_OP &&
381 (tree->opval.op != FUNCTION &&
382 tree->opval.op != BLOCK &&
383 tree->opval.op != NULLOP))
385 filename = tree->filename;
386 lineno = tree->lineno;
389 /* make sure we resolve the true & false labels for ifx */
390 if (tree->type == EX_OP && tree->opval.op == IFX)
396 if ((csym = findSym (LabelTab, tree->trueLabel,
397 tree->trueLabel->name)))
398 tree->trueLabel = csym;
400 werror (E_LABEL_UNDEF, tree->trueLabel->name);
403 if (tree->falseLabel)
405 if ((csym = findSym (LabelTab,
407 tree->falseLabel->name)))
408 tree->falseLabel = csym;
410 werror (E_LABEL_UNDEF, tree->falseLabel->name);
415 /* if this is a label resolve it from the labelTab */
416 if (IS_AST_VALUE (tree) &&
417 tree->opval.val->sym &&
418 tree->opval.val->sym->islbl)
421 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
422 tree->opval.val->sym->name);
425 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
427 tree->opval.val->sym = csym;
429 goto resolveChildren;
432 /* do only for leafs */
433 if (IS_AST_VALUE (tree) &&
434 tree->opval.val->sym &&
435 !tree->opval.val->sym->implicit)
438 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
440 /* if found in the symbol table & they r not the same */
441 if (csym && tree->opval.val->sym != csym)
443 tree->opval.val->sym = csym;
444 tree->opval.val->type = csym->type;
445 tree->opval.val->etype = csym->etype;
448 /* if not found in the symbol table */
449 /* mark it as undefined assume it is */
450 /* an integer in data space */
451 if (!csym && !tree->opval.val->sym->implicit)
454 /* if this is a function name then */
455 /* mark it as returning an int */
458 tree->opval.val->sym->type = newLink ();
459 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
460 tree->opval.val->sym->type->next =
461 tree->opval.val->sym->etype = newIntLink ();
462 tree->opval.val->etype = tree->opval.val->etype;
463 tree->opval.val->type = tree->opval.val->sym->type;
464 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
468 tree->opval.val->sym->undefined = 1;
469 tree->opval.val->type =
470 tree->opval.val->etype = newIntLink ();
471 tree->opval.val->sym->type =
472 tree->opval.val->sym->etype = newIntLink ();
478 resolveSymbols (tree->left);
479 resolveSymbols (tree->right);
484 /*-----------------------------------------------------------------*/
485 /* setAstLineno - walks a ast tree & sets the line number */
486 /*-----------------------------------------------------------------*/
488 setAstLineno (ast * tree, int lineno)
493 tree->lineno = lineno;
494 setAstLineno (tree->left, lineno);
495 setAstLineno (tree->right, lineno);
500 /* this functions seems to be superfluous?! kmh */
502 /*-----------------------------------------------------------------*/
503 /* resolveFromTable - will return the symbal table value */
504 /*-----------------------------------------------------------------*/
506 resolveFromTable (value * val)
513 csym = findSymWithLevel (SymbolTab, val->sym);
515 /* if found in the symbol table & they r not the same */
516 if (csym && val->sym != csym &&
517 csym->level == val->sym->level &&
523 val->type = csym->type;
524 val->etype = csym->etype;
531 /*-----------------------------------------------------------------*/
532 /* funcOfType :- function of type with name */
533 /*-----------------------------------------------------------------*/
535 funcOfType (char *name, sym_link * type, sym_link * argType,
539 /* create the symbol */
540 sym = newSymbol (name, 0);
542 /* if arguments required */
547 args = sym->args = newValue ();
551 args->type = copyLinkChain (argType);
552 args->etype = getSpec (args->type);
555 args = args->next = newValue ();
559 /* setup return value */
560 sym->type = newLink ();
561 DCL_TYPE (sym->type) = FUNCTION;
562 sym->type->next = copyLinkChain (type);
563 sym->etype = getSpec (sym->type);
564 SPEC_RENT (sym->etype) = rent;
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,
608 sym_link *fetype = func->etype;
610 /* if none of them exist */
611 if (!defParm && !actParm)
615 if (getenv("DEBUG_SANITY")) {
616 fprintf (stderr, "addSym: %s ", defParm->name);
618 /* make sure the type is complete and sane */
619 checkTypeSanity(defParm->etype, defParm->name);
622 /* if the function is being called via a pointer & */
623 /* it has not been defined a reentrant then we cannot */
624 /* have parameters */
625 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
627 werror (E_NONRENT_ARGS);
631 /* if defined parameters ended but actual parameters */
632 /* exist and this is not defined as a variable arg */
633 /* also check if statckAuto option is specified */
634 if ((!defParm) && actParm && (!func->hasVargs) &&
635 !options.stackAuto && !IS_RENT (fetype))
637 werror (E_TOO_MANY_PARMS);
641 /* if defined parameters present but no actual parameters */
642 if (defParm && !actParm)
644 werror (E_TOO_FEW_PARMS);
648 /* If this is a varargs function... */
649 if (!defParm && actParm && func->hasVargs)
654 if (IS_CAST_OP (actParm)
655 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
657 /* Parameter was explicitly typecast; don't touch it. */
661 /* The ternary ('?') operator is weird: the ftype of the
662 * operator is the type of the condition, but it will return a
663 * (possibly) different type.
665 if (IS_TERNARY_OP(actParm))
667 assert(IS_COLON_OP(actParm->right));
668 assert(actParm->right->left);
669 ftype = actParm->right->left->ftype;
673 ftype = actParm->ftype;
676 /* If it's a small integer, upcast to int. */
677 if (IS_INTEGRAL (ftype)
678 && (getSize (ftype) < (unsigned) INTSIZE))
680 newType = newAst_LINK(INTTYPE);
683 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
685 newType = newAst_LINK (copyLinkChain(ftype));
686 DCL_TYPE (newType->opval.lnk) = GPOINTER;
689 if (IS_AGGREGATE (ftype))
691 newType = newAst_LINK (copyLinkChain (ftype));
692 DCL_TYPE (newType->opval.lnk) = GPOINTER;
696 /* cast required; change this op to a cast. */
697 ast *parmCopy = resolveSymbols (copyAst (actParm));
699 actParm->type = EX_OP;
700 actParm->opval.op = CAST;
701 actParm->left = newType;
702 actParm->right = parmCopy;
703 decorateType (actParm);
705 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
707 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
708 processParms (func, NULL, actParm->right, parmNumber, rightmost));
713 /* if defined parameters ended but actual has not & */
715 if (!defParm && actParm &&
716 (options.stackAuto || IS_RENT (fetype)))
719 resolveSymbols (actParm);
720 /* if this is a PARAM node then match left & right */
721 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
723 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
724 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
728 /* If we have found a value node by following only right-hand links,
729 * then we know that there are no more values after us.
731 * Therefore, if there are more defined parameters, the caller didn't
734 if (rightmost && defParm->next)
736 werror (E_TOO_FEW_PARMS);
741 /* the parameter type must be at least castable */
742 if (checkType (defParm->type, actParm->ftype) == 0)
744 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
745 werror (E_CONTINUE, "defined type ");
746 printTypeChain (defParm->type, stderr);
747 fprintf (stderr, "\n");
748 werror (E_CONTINUE, "actual type ");
749 printTypeChain (actParm->ftype, stderr);
750 fprintf (stderr, "\n");
753 /* if the parameter is castable then add the cast */
754 if (checkType (defParm->type, actParm->ftype) < 0)
756 ast *pTree = resolveSymbols (copyAst (actParm));
758 /* now change the current one to a cast */
759 actParm->type = EX_OP;
760 actParm->opval.op = CAST;
761 actParm->left = newAst_LINK (defParm->type);
762 actParm->right = pTree;
763 actParm->etype = defParm->etype;
764 actParm->ftype = defParm->type;
767 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
769 actParm->argSym = defParm->sym;
770 /* make a copy and change the regparm type to the defined parm */
771 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
772 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
776 /*-----------------------------------------------------------------*/
777 /* createIvalType - generates ival for basic types */
778 /*-----------------------------------------------------------------*/
780 createIvalType (ast * sym, sym_link * type, initList * ilist)
784 /* if initList is deep */
785 if (ilist->type == INIT_DEEP)
786 ilist = ilist->init.deep;
788 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
789 return decorateType (newNode ('=', sym, iExpr));
792 /*-----------------------------------------------------------------*/
793 /* createIvalStruct - generates initial value for structures */
794 /*-----------------------------------------------------------------*/
796 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
802 sflds = SPEC_STRUCT (type)->fields;
803 if (ilist->type != INIT_DEEP)
805 werror (E_INIT_STRUCT, "");
809 iloop = ilist->init.deep;
811 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
815 /* if we have come to end */
819 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
820 lAst = decorateType (resolveSymbols (lAst));
821 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
827 /*-----------------------------------------------------------------*/
828 /* createIvalArray - generates code for array initialization */
829 /*-----------------------------------------------------------------*/
831 createIvalArray (ast * sym, sym_link * type, initList * ilist)
835 int lcnt = 0, size = 0;
837 /* take care of the special case */
838 /* array of characters can be init */
840 if (IS_CHAR (type->next))
841 if ((rast = createIvalCharPtr (sym,
843 decorateType (resolveSymbols (list2expr (ilist))))))
845 return decorateType (resolveSymbols (rast));
847 /* not the special case */
848 if (ilist->type != INIT_DEEP)
850 werror (E_INIT_STRUCT, "");
854 iloop = ilist->init.deep;
855 lcnt = DCL_ELEM (type);
862 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
863 aSym = decorateType (resolveSymbols (aSym));
864 rast = createIval (aSym, type->next, iloop, rast);
865 iloop = (iloop ? iloop->next : NULL);
868 /* if not array limits given & we */
869 /* are out of initialisers then */
870 if (!DCL_ELEM (type) && !iloop)
873 /* no of elements given and we */
874 /* have generated for all of them */
876 /* if initializers left */
878 // there has to be a better way
879 char *name=sym->opval.val->sym->name;
880 int lineno=sym->opval.val->sym->lineDef;
881 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
887 /* if we have not been given a size */
888 if (!DCL_ELEM (type))
889 DCL_ELEM (type) = size;
891 return decorateType (resolveSymbols (rast));
895 /*-----------------------------------------------------------------*/
896 /* createIvalCharPtr - generates initial values for char pointers */
897 /*-----------------------------------------------------------------*/
899 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
903 /* if this is a pointer & right is a literal array then */
904 /* just assignment will do */
905 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
906 SPEC_SCLS (iexpr->etype) == S_CODE)
907 && IS_ARRAY (iexpr->ftype)))
908 return newNode ('=', sym, iexpr);
910 /* left side is an array so we have to assign each */
912 if ((IS_LITERAL (iexpr->etype) ||
913 SPEC_SCLS (iexpr->etype) == S_CODE)
914 && IS_ARRAY (iexpr->ftype))
917 /* for each character generate an assignment */
918 /* to the array element */
919 char *s = SPEC_CVAL (iexpr->etype).v_char;
924 rast = newNode (NULLOP,
928 newAst_VALUE (valueFromLit ((float) i))),
929 newAst_VALUE (valueFromLit (*s))));
933 rast = newNode (NULLOP,
937 newAst_VALUE (valueFromLit ((float) i))),
938 newAst_VALUE (valueFromLit (*s))));
939 return decorateType (resolveSymbols (rast));
945 /*-----------------------------------------------------------------*/
946 /* createIvalPtr - generates initial value for pointers */
947 /*-----------------------------------------------------------------*/
949 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
955 if (ilist->type == INIT_DEEP)
956 ilist = ilist->init.deep;
958 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
960 /* if character pointer */
961 if (IS_CHAR (type->next))
962 if ((rast = createIvalCharPtr (sym, type, iexpr)))
965 return newNode ('=', sym, iexpr);
968 /*-----------------------------------------------------------------*/
969 /* createIval - generates code for initial value */
970 /*-----------------------------------------------------------------*/
972 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
979 /* if structure then */
980 if (IS_STRUCT (type))
981 rast = createIvalStruct (sym, type, ilist);
983 /* if this is a pointer */
985 rast = createIvalPtr (sym, type, ilist);
987 /* if this is an array */
989 rast = createIvalArray (sym, type, ilist);
991 /* if type is SPECIFIER */
993 rast = createIvalType (sym, type, ilist);
995 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
997 return decorateType (resolveSymbols (rast));
1000 /*-----------------------------------------------------------------*/
1001 /* initAggregates - initialises aggregate variables with initv */
1002 /*-----------------------------------------------------------------*/
1004 initAggregates (symbol * sym, initList * ival, ast * wid)
1006 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1009 /*-----------------------------------------------------------------*/
1010 /* gatherAutoInit - creates assignment expressions for initial */
1012 /*-----------------------------------------------------------------*/
1014 gatherAutoInit (symbol * autoChain)
1021 for (sym = autoChain; sym; sym = sym->next)
1024 /* resolve the symbols in the ival */
1026 resolveIvalSym (sym->ival);
1028 /* if this is a static variable & has an */
1029 /* initial value the code needs to be lifted */
1030 /* here to the main portion since they can be */
1031 /* initialised only once at the start */
1032 if (IS_STATIC (sym->etype) && sym->ival &&
1033 SPEC_SCLS (sym->etype) != S_CODE)
1037 // this can only be a constant
1038 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1039 werror (E_CONST_EXPECTED);
1042 /* insert the symbol into the symbol table */
1043 /* with level = 0 & name = rname */
1044 newSym = copySymbol (sym);
1045 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1047 /* now lift the code to main */
1048 if (IS_AGGREGATE (sym->type))
1049 work = initAggregates (sym, sym->ival, NULL);
1051 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1052 list2expr (sym->ival));
1054 setAstLineno (work, sym->lineDef);
1058 staticAutos = newNode (NULLOP, staticAutos, work);
1065 /* if there is an initial value */
1066 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1068 if (IS_AGGREGATE (sym->type))
1069 work = initAggregates (sym, sym->ival, NULL);
1071 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1072 list2expr (sym->ival));
1074 setAstLineno (work, sym->lineDef);
1077 init = newNode (NULLOP, init, work);
1086 /*-----------------------------------------------------------------*/
1087 /* stringToSymbol - creates a symbol from a literal string */
1088 /*-----------------------------------------------------------------*/
1090 stringToSymbol (value * val)
1092 char name[SDCC_NAME_MAX + 1];
1093 static int charLbl = 0;
1096 sprintf (name, "_str_%d", charLbl++);
1097 sym = newSymbol (name, 0); /* make it @ level 0 */
1098 strcpy (sym->rname, name);
1100 /* copy the type from the value passed */
1101 sym->type = copyLinkChain (val->type);
1102 sym->etype = getSpec (sym->type);
1103 /* change to storage class & output class */
1104 SPEC_SCLS (sym->etype) = S_CODE;
1105 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1106 SPEC_STAT (sym->etype) = 1;
1107 /* make the level & block = 0 */
1108 sym->block = sym->level = 0;
1110 /* create an ival */
1111 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1116 allocVariables (sym);
1119 return symbolVal (sym);
1123 /*-----------------------------------------------------------------*/
1124 /* processBlockVars - will go thru the ast looking for block if */
1125 /* a block is found then will allocate the syms */
1126 /* will also gather the auto inits present */
1127 /*-----------------------------------------------------------------*/
1129 processBlockVars (ast * tree, int *stack, int action)
1134 /* if this is a block */
1135 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1139 if (action == ALLOCATE)
1141 autoInit = gatherAutoInit (tree->values.sym);
1142 *stack += allocVariables (tree->values.sym);
1144 /* if there are auto inits then do them */
1146 tree->left = newNode (NULLOP, autoInit, tree->left);
1148 else /* action is deallocate */
1149 deallocLocal (tree->values.sym);
1152 processBlockVars (tree->left, stack, action);
1153 processBlockVars (tree->right, stack, action);
1157 /*-----------------------------------------------------------------*/
1158 /* constExprValue - returns the value of a constant expression */
1159 /*-----------------------------------------------------------------*/
1161 constExprValue (ast * cexpr, int check)
1163 cexpr = decorateType (resolveSymbols (cexpr));
1165 /* if this is not a constant then */
1166 if (!IS_LITERAL (cexpr->ftype))
1168 /* then check if this is a literal array
1170 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1171 SPEC_CVAL (cexpr->etype).v_char &&
1172 IS_ARRAY (cexpr->ftype))
1174 value *val = valFromType (cexpr->ftype);
1175 SPEC_SCLS (val->etype) = S_LITERAL;
1176 val->sym = cexpr->opval.val->sym;
1177 val->sym->type = copyLinkChain (cexpr->ftype);
1178 val->sym->etype = getSpec (val->sym->type);
1179 strcpy (val->name, cexpr->opval.val->sym->rname);
1183 /* if we are casting a literal value then */
1184 if (IS_AST_OP (cexpr) &&
1185 cexpr->opval.op == CAST &&
1186 IS_LITERAL (cexpr->left->ftype))
1187 return valCastLiteral (cexpr->ftype,
1188 floatFromVal (cexpr->left->opval.val));
1190 if (IS_AST_VALUE (cexpr))
1191 return cexpr->opval.val;
1194 werror (E_CONST_EXPECTED, "found expression");
1199 /* return the value */
1200 return cexpr->opval.val;
1204 /*-----------------------------------------------------------------*/
1205 /* isLabelInAst - will return true if a given label is found */
1206 /*-----------------------------------------------------------------*/
1208 isLabelInAst (symbol * label, ast * tree)
1210 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1213 if (IS_AST_OP (tree) &&
1214 tree->opval.op == LABEL &&
1215 isSymbolEqual (AST_SYMBOL (tree->left), label))
1218 return isLabelInAst (label, tree->right) &&
1219 isLabelInAst (label, tree->left);
1223 /*-----------------------------------------------------------------*/
1224 /* isLoopCountable - return true if the loop count can be determi- */
1225 /* -ned at compile time . */
1226 /*-----------------------------------------------------------------*/
1228 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1229 symbol ** sym, ast ** init, ast ** end)
1232 /* the loop is considered countable if the following
1233 conditions are true :-
1235 a) initExpr :- <sym> = <const>
1236 b) condExpr :- <sym> < <const1>
1237 c) loopExpr :- <sym> ++
1240 /* first check the initExpr */
1241 if (IS_AST_OP (initExpr) &&
1242 initExpr->opval.op == '=' && /* is assignment */
1243 IS_AST_SYM_VALUE (initExpr->left))
1244 { /* left is a symbol */
1246 *sym = AST_SYMBOL (initExpr->left);
1247 *init = initExpr->right;
1252 /* for now the symbol has to be of
1254 if (!IS_INTEGRAL ((*sym)->type))
1257 /* now check condExpr */
1258 if (IS_AST_OP (condExpr))
1261 switch (condExpr->opval.op)
1264 if (IS_AST_SYM_VALUE (condExpr->left) &&
1265 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1266 IS_AST_LIT_VALUE (condExpr->right))
1268 *end = condExpr->right;
1274 if (IS_AST_OP (condExpr->left) &&
1275 condExpr->left->opval.op == '>' &&
1276 IS_AST_LIT_VALUE (condExpr->left->right) &&
1277 IS_AST_SYM_VALUE (condExpr->left->left) &&
1278 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1281 *end = newNode ('+', condExpr->left->right,
1282 newAst_VALUE (constVal ("1")));
1293 /* check loop expression is of the form <sym>++ */
1294 if (!IS_AST_OP (loopExpr))
1297 /* check if <sym> ++ */
1298 if (loopExpr->opval.op == INC_OP)
1304 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1305 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1312 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1313 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1321 if (loopExpr->opval.op == ADD_ASSIGN)
1324 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1325 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1326 IS_AST_LIT_VALUE (loopExpr->right) &&
1327 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1335 /*-----------------------------------------------------------------*/
1336 /* astHasVolatile - returns true if ast contains any volatile */
1337 /*-----------------------------------------------------------------*/
1339 astHasVolatile (ast * tree)
1344 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1347 if (IS_AST_OP (tree))
1348 return astHasVolatile (tree->left) ||
1349 astHasVolatile (tree->right);
1354 /*-----------------------------------------------------------------*/
1355 /* astHasPointer - return true if the ast contains any ptr variable */
1356 /*-----------------------------------------------------------------*/
1358 astHasPointer (ast * tree)
1363 if (IS_AST_LINK (tree))
1366 /* if we hit an array expression then check
1367 only the left side */
1368 if (IS_AST_OP (tree) && tree->opval.op == '[')
1369 return astHasPointer (tree->left);
1371 if (IS_AST_VALUE (tree))
1372 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1374 return astHasPointer (tree->left) ||
1375 astHasPointer (tree->right);
1379 /*-----------------------------------------------------------------*/
1380 /* astHasSymbol - return true if the ast has the given symbol */
1381 /*-----------------------------------------------------------------*/
1383 astHasSymbol (ast * tree, symbol * sym)
1385 if (!tree || IS_AST_LINK (tree))
1388 if (IS_AST_VALUE (tree))
1390 if (IS_AST_SYM_VALUE (tree))
1391 return isSymbolEqual (AST_SYMBOL (tree), sym);
1396 return astHasSymbol (tree->left, sym) ||
1397 astHasSymbol (tree->right, sym);
1400 /*-----------------------------------------------------------------*/
1401 /* isConformingBody - the loop body has to conform to a set of rules */
1402 /* for the loop to be considered reversible read on for rules */
1403 /*-----------------------------------------------------------------*/
1405 isConformingBody (ast * pbody, symbol * sym, ast * body)
1408 /* we are going to do a pre-order traversal of the
1409 tree && check for the following conditions. (essentially
1410 a set of very shallow tests )
1411 a) the sym passed does not participate in
1412 any arithmetic operation
1413 b) There are no function calls
1414 c) all jumps are within the body
1415 d) address of loop control variable not taken
1416 e) if an assignment has a pointer on the
1417 left hand side make sure right does not have
1418 loop control variable */
1420 /* if we reach the end or a leaf then true */
1421 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1425 /* if anything else is "volatile" */
1426 if (IS_VOLATILE (TETYPE (pbody)))
1429 /* we will walk the body in a pre-order traversal for
1431 switch (pbody->opval.op)
1433 /*------------------------------------------------------------------*/
1435 return isConformingBody (pbody->right, sym, body);
1437 /*------------------------------------------------------------------*/
1442 /*------------------------------------------------------------------*/
1443 case INC_OP: /* incerement operator unary so left only */
1446 /* sure we are not sym is not modified */
1448 IS_AST_SYM_VALUE (pbody->left) &&
1449 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1453 IS_AST_SYM_VALUE (pbody->right) &&
1454 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1459 /*------------------------------------------------------------------*/
1461 case '*': /* can be unary : if right is null then unary operation */
1466 /* if right is NULL then unary operation */
1467 /*------------------------------------------------------------------*/
1468 /*----------------------------*/
1470 /*----------------------------*/
1473 if (IS_AST_SYM_VALUE (pbody->left) &&
1474 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1477 return isConformingBody (pbody->left, sym, body);
1481 if (astHasSymbol (pbody->left, sym) ||
1482 astHasSymbol (pbody->right, sym))
1487 /*------------------------------------------------------------------*/
1495 if (IS_AST_SYM_VALUE (pbody->left) &&
1496 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1499 if (IS_AST_SYM_VALUE (pbody->right) &&
1500 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1503 return isConformingBody (pbody->left, sym, body) &&
1504 isConformingBody (pbody->right, sym, body);
1511 if (IS_AST_SYM_VALUE (pbody->left) &&
1512 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1514 return isConformingBody (pbody->left, sym, body);
1516 /*------------------------------------------------------------------*/
1528 case SIZEOF: /* evaluate wihout code generation */
1530 return isConformingBody (pbody->left, sym, body) &&
1531 isConformingBody (pbody->right, sym, body);
1533 /*------------------------------------------------------------------*/
1536 /* if left has a pointer & right has loop
1537 control variable then we cannot */
1538 if (astHasPointer (pbody->left) &&
1539 astHasSymbol (pbody->right, sym))
1541 if (astHasVolatile (pbody->left))
1544 if (IS_AST_SYM_VALUE (pbody->left) &&
1545 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1548 if (astHasVolatile (pbody->left))
1551 return isConformingBody (pbody->left, sym, body) &&
1552 isConformingBody (pbody->right, sym, body);
1563 assert ("Parser should not have generated this\n");
1565 /*------------------------------------------------------------------*/
1566 /*----------------------------*/
1567 /* comma operator */
1568 /*----------------------------*/
1570 return isConformingBody (pbody->left, sym, body) &&
1571 isConformingBody (pbody->right, sym, body);
1573 /*------------------------------------------------------------------*/
1574 /*----------------------------*/
1576 /*----------------------------*/
1580 /*------------------------------------------------------------------*/
1581 /*----------------------------*/
1582 /* return statement */
1583 /*----------------------------*/
1588 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1593 if (astHasSymbol (pbody->left, sym))
1600 return isConformingBody (pbody->left, sym, body) &&
1601 isConformingBody (pbody->right, sym, body);
1607 /*-----------------------------------------------------------------*/
1608 /* isLoopReversible - takes a for loop as input && returns true */
1609 /* if the for loop is reversible. If yes will set the value of */
1610 /* the loop control var & init value & termination value */
1611 /*-----------------------------------------------------------------*/
1613 isLoopReversible (ast * loop, symbol ** loopCntrl,
1614 ast ** init, ast ** end)
1616 /* if option says don't do it then don't */
1617 if (optimize.noLoopReverse)
1619 /* there are several tests to determine this */
1621 /* for loop has to be of the form
1622 for ( <sym> = <const1> ;
1623 [<sym> < <const2>] ;
1624 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1626 if (!isLoopCountable (AST_FOR (loop, initExpr),
1627 AST_FOR (loop, condExpr),
1628 AST_FOR (loop, loopExpr),
1629 loopCntrl, init, end))
1632 /* now do some serious checking on the body of the loop
1635 return isConformingBody (loop->left, *loopCntrl, loop->left);
1639 /*-----------------------------------------------------------------*/
1640 /* replLoopSym - replace the loop sym by loop sym -1 */
1641 /*-----------------------------------------------------------------*/
1643 replLoopSym (ast * body, symbol * sym)
1646 if (!body || IS_AST_LINK (body))
1649 if (IS_AST_SYM_VALUE (body))
1652 if (isSymbolEqual (AST_SYMBOL (body), sym))
1656 body->opval.op = '-';
1657 body->left = newAst_VALUE (symbolVal (sym));
1658 body->right = newAst_VALUE (constVal ("1"));
1666 replLoopSym (body->left, sym);
1667 replLoopSym (body->right, sym);
1671 /*-----------------------------------------------------------------*/
1672 /* reverseLoop - do the actual loop reversal */
1673 /*-----------------------------------------------------------------*/
1675 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1679 /* create the following tree
1684 if (sym) goto for_continue ;
1687 /* put it together piece by piece */
1688 rloop = newNode (NULLOP,
1689 createIf (newAst_VALUE (symbolVal (sym)),
1691 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1694 newAst_VALUE (symbolVal (sym)),
1697 replLoopSym (loop->left, sym);
1699 rloop = newNode (NULLOP,
1701 newAst_VALUE (symbolVal (sym)),
1702 newNode ('-', end, init)),
1703 createLabel (AST_FOR (loop, continueLabel),
1707 newNode (SUB_ASSIGN,
1708 newAst_VALUE (symbolVal (sym)),
1709 newAst_VALUE (constVal ("1"))),
1712 return decorateType (rloop);
1716 #define DEMAND_INTEGER_PROMOTION
1718 #ifdef DEMAND_INTEGER_PROMOTION
1720 /*-----------------------------------------------------------------*/
1721 /* walk a tree looking for the leaves. Add a typecast to the given */
1722 /* type to each value leaf node. */
1723 /*-----------------------------------------------------------------*/
1725 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1727 if (!node || IS_CALLOP(node))
1729 /* WTF? We should never get here. */
1733 if (!node->left && !node->right)
1735 /* We're at a leaf; if it's a value, apply the typecast */
1736 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1738 *parentPtr = decorateType (newNode (CAST,
1739 newAst_LINK (copyLinkChain (type)),
1747 pushTypeCastToLeaves (type, node->left, &(node->left));
1751 pushTypeCastToLeaves (type, node->right, &(node->right));
1758 /*-----------------------------------------------------------------*/
1759 /* Given an assignment operation in a tree, determine if the LHS */
1760 /* (the result) has a different (integer) type than the RHS. */
1761 /* If so, walk the RHS and add a typecast to the type of the LHS */
1762 /* to all leaf nodes. */
1763 /*-----------------------------------------------------------------*/
1765 propAsgType (ast * tree)
1767 #ifdef DEMAND_INTEGER_PROMOTION
1768 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1770 /* Nothing to do here... */
1774 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1776 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1783 /*-----------------------------------------------------------------*/
1784 /* decorateType - compute type for this tree also does type cheking */
1785 /* this is done bottom up, since type have to flow upwards */
1786 /* it also does constant folding, and paramater checking */
1787 /*-----------------------------------------------------------------*/
1789 decorateType (ast * tree)
1797 /* if already has type then do nothing */
1798 if (tree->decorated)
1801 tree->decorated = 1;
1803 /* print the line */
1804 /* if not block & function */
1805 if (tree->type == EX_OP &&
1806 (tree->opval.op != FUNCTION &&
1807 tree->opval.op != BLOCK &&
1808 tree->opval.op != NULLOP))
1810 filename = tree->filename;
1811 lineno = tree->lineno;
1814 /* if any child is an error | this one is an error do nothing */
1815 if (tree->isError ||
1816 (tree->left && tree->left->isError) ||
1817 (tree->right && tree->right->isError))
1820 /*------------------------------------------------------------------*/
1821 /*----------------------------*/
1822 /* leaf has been reached */
1823 /*----------------------------*/
1824 /* if this is of type value */
1825 /* just get the type */
1826 if (tree->type == EX_VALUE)
1829 if (IS_LITERAL (tree->opval.val->etype))
1832 /* if this is a character array then declare it */
1833 if (IS_ARRAY (tree->opval.val->type))
1834 tree->opval.val = stringToSymbol (tree->opval.val);
1836 /* otherwise just copy the type information */
1837 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1838 if (funcInChain (tree->opval.val->type))
1840 tree->hasVargs = tree->opval.val->sym->hasVargs;
1841 tree->args = copyValueChain (tree->opval.val->sym->args);
1846 if (tree->opval.val->sym)
1848 /* if the undefined flag is set then give error message */
1849 if (tree->opval.val->sym->undefined)
1851 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1853 TTYPE (tree) = TETYPE (tree) =
1854 tree->opval.val->type = tree->opval.val->sym->type =
1855 tree->opval.val->etype = tree->opval.val->sym->etype =
1856 copyLinkChain (INTTYPE);
1861 /* if impilicit i.e. struct/union member then no type */
1862 if (tree->opval.val->sym->implicit)
1863 TTYPE (tree) = TETYPE (tree) = NULL;
1868 /* else copy the type */
1869 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1871 /* and mark it as referenced */
1872 tree->opval.val->sym->isref = 1;
1873 /* if this is of type function or function pointer */
1874 if (funcInChain (tree->opval.val->type))
1876 tree->hasVargs = tree->opval.val->sym->hasVargs;
1877 tree->args = copyValueChain (tree->opval.val->sym->args);
1887 /* if type link for the case of cast */
1888 if (tree->type == EX_LINK)
1890 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1897 dtl = decorateType (tree->left);
1898 dtr = decorateType (tree->right);
1900 /* this is to take care of situations
1901 when the tree gets rewritten */
1902 if (dtl != tree->left)
1904 if (dtr != tree->right)
1908 /* depending on type of operator do */
1910 switch (tree->opval.op)
1912 /*------------------------------------------------------------------*/
1913 /*----------------------------*/
1915 /*----------------------------*/
1918 /* determine which is the array & which the index */
1919 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1922 ast *tempTree = tree->left;
1923 tree->left = tree->right;
1924 tree->right = tempTree;
1927 /* first check if this is a array or a pointer */
1928 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1930 werror (E_NEED_ARRAY_PTR, "[]");
1931 goto errorTreeReturn;
1934 /* check if the type of the idx */
1935 if (!IS_INTEGRAL (RTYPE (tree)))
1937 werror (E_IDX_NOT_INT);
1938 goto errorTreeReturn;
1941 /* if the left is an rvalue then error */
1944 werror (E_LVALUE_REQUIRED, "array access");
1945 goto errorTreeReturn;
1948 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1949 if (IS_PTR(LTYPE(tree))) {
1950 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1954 /*------------------------------------------------------------------*/
1955 /*----------------------------*/
1957 /*----------------------------*/
1959 /* if this is not a structure */
1960 if (!IS_STRUCT (LTYPE (tree)))
1962 werror (E_STRUCT_UNION, ".");
1963 goto errorTreeReturn;
1965 TTYPE (tree) = structElemType (LTYPE (tree),
1966 (tree->right->type == EX_VALUE ?
1967 tree->right->opval.val : NULL), &tree->args);
1968 TETYPE (tree) = getSpec (TTYPE (tree));
1971 /*------------------------------------------------------------------*/
1972 /*----------------------------*/
1973 /* struct/union pointer */
1974 /*----------------------------*/
1976 /* if not pointer to a structure */
1977 if (!IS_PTR (LTYPE (tree)))
1979 werror (E_PTR_REQD);
1980 goto errorTreeReturn;
1983 if (!IS_STRUCT (LTYPE (tree)->next))
1985 werror (E_STRUCT_UNION, "->");
1986 goto errorTreeReturn;
1989 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1990 (tree->right->type == EX_VALUE ?
1991 tree->right->opval.val : NULL), &tree->args);
1992 TETYPE (tree) = getSpec (TTYPE (tree));
1995 /*------------------------------------------------------------------*/
1996 /*----------------------------*/
1997 /* ++/-- operation */
1998 /*----------------------------*/
1999 case INC_OP: /* incerement operator unary so left only */
2002 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2003 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2004 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
2005 werror (E_CODE_WRITE, "++/--");
2014 /*------------------------------------------------------------------*/
2015 /*----------------------------*/
2017 /*----------------------------*/
2018 case '&': /* can be unary */
2019 /* if right is NULL then unary operation */
2020 if (tree->right) /* not an unary operation */
2023 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2025 werror (E_BITWISE_OP);
2026 werror (E_CONTINUE, "left & right types are ");
2027 printTypeChain (LTYPE (tree), stderr);
2028 fprintf (stderr, ",");
2029 printTypeChain (RTYPE (tree), stderr);
2030 fprintf (stderr, "\n");
2031 goto errorTreeReturn;
2034 /* if they are both literal */
2035 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2037 tree->type = EX_VALUE;
2038 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2039 valFromType (RETYPE (tree)), '&');
2041 tree->right = tree->left = NULL;
2042 TETYPE (tree) = tree->opval.val->etype;
2043 TTYPE (tree) = tree->opval.val->type;
2047 /* see if this is a GETHBIT operation if yes
2050 ast *otree = optimizeGetHbit (tree);
2053 return decorateType (otree);
2056 /* if right or left is literal then result of that type */
2057 if (IS_LITERAL (RTYPE (tree)))
2060 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2061 TETYPE (tree) = getSpec (TTYPE (tree));
2062 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2066 if (IS_LITERAL (LTYPE (tree)))
2068 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2069 TETYPE (tree) = getSpec (TTYPE (tree));
2070 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2076 computeType (LTYPE (tree), RTYPE (tree));
2077 TETYPE (tree) = getSpec (TTYPE (tree));
2080 LRVAL (tree) = RRVAL (tree) = 1;
2084 /*------------------------------------------------------------------*/
2085 /*----------------------------*/
2087 /*----------------------------*/
2089 p->class = DECLARATOR;
2090 /* if bit field then error */
2091 if (IS_BITVAR (tree->left->etype))
2093 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2094 goto errorTreeReturn;
2097 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2099 werror (E_ILLEGAL_ADDR, "address of register variable");
2100 goto errorTreeReturn;
2103 if (IS_FUNC (LTYPE (tree)))
2105 werror (E_ILLEGAL_ADDR, "address of function");
2106 goto errorTreeReturn;
2111 werror (E_LVALUE_REQUIRED, "address of");
2112 goto errorTreeReturn;
2114 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2116 DCL_TYPE (p) = CPOINTER;
2117 DCL_PTR_CONST (p) = port->mem.code_ro;
2119 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2120 DCL_TYPE (p) = FPOINTER;
2121 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2122 DCL_TYPE (p) = PPOINTER;
2123 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2124 DCL_TYPE (p) = IPOINTER;
2125 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2126 DCL_TYPE (p) = EEPPOINTER;
2128 DCL_TYPE (p) = POINTER;
2130 if (IS_AST_SYM_VALUE (tree->left))
2132 AST_SYMBOL (tree->left)->addrtaken = 1;
2133 AST_SYMBOL (tree->left)->allocreq = 1;
2136 p->next = LTYPE (tree);
2138 TETYPE (tree) = getSpec (TTYPE (tree));
2139 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2140 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2145 /*------------------------------------------------------------------*/
2146 /*----------------------------*/
2148 /*----------------------------*/
2150 /* if the rewrite succeeds then don't go any furthur */
2152 ast *wtree = optimizeRRCRLC (tree);
2154 return decorateType (wtree);
2156 /*------------------------------------------------------------------*/
2157 /*----------------------------*/
2159 /*----------------------------*/
2161 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2163 werror (E_BITWISE_OP);
2164 werror (E_CONTINUE, "left & right types are ");
2165 printTypeChain (LTYPE (tree), stderr);
2166 fprintf (stderr, ",");
2167 printTypeChain (RTYPE (tree), stderr);
2168 fprintf (stderr, "\n");
2169 goto errorTreeReturn;
2172 /* if they are both literal then */
2173 /* rewrite the tree */
2174 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2176 tree->type = EX_VALUE;
2177 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2178 valFromType (RETYPE (tree)),
2180 tree->right = tree->left = NULL;
2181 TETYPE (tree) = tree->opval.val->etype;
2182 TTYPE (tree) = tree->opval.val->type;
2185 LRVAL (tree) = RRVAL (tree) = 1;
2186 TETYPE (tree) = getSpec (TTYPE (tree) =
2187 computeType (LTYPE (tree),
2190 /*------------------------------------------------------------------*/
2191 /*----------------------------*/
2193 /*----------------------------*/
2195 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2197 werror (E_INVALID_OP, "divide");
2198 goto errorTreeReturn;
2200 /* if they are both literal then */
2201 /* rewrite the tree */
2202 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2204 tree->type = EX_VALUE;
2205 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2206 valFromType (RETYPE (tree)));
2207 tree->right = tree->left = NULL;
2208 TETYPE (tree) = getSpec (TTYPE (tree) =
2209 tree->opval.val->type);
2212 LRVAL (tree) = RRVAL (tree) = 1;
2213 TETYPE (tree) = getSpec (TTYPE (tree) =
2214 computeType (LTYPE (tree),
2218 /*------------------------------------------------------------------*/
2219 /*----------------------------*/
2221 /*----------------------------*/
2223 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2225 werror (E_BITWISE_OP);
2226 werror (E_CONTINUE, "left & right types are ");
2227 printTypeChain (LTYPE (tree), stderr);
2228 fprintf (stderr, ",");
2229 printTypeChain (RTYPE (tree), stderr);
2230 fprintf (stderr, "\n");
2231 goto errorTreeReturn;
2233 /* if they are both literal then */
2234 /* rewrite the tree */
2235 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2237 tree->type = EX_VALUE;
2238 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2239 valFromType (RETYPE (tree)));
2240 tree->right = tree->left = NULL;
2241 TETYPE (tree) = getSpec (TTYPE (tree) =
2242 tree->opval.val->type);
2245 LRVAL (tree) = RRVAL (tree) = 1;
2246 TETYPE (tree) = getSpec (TTYPE (tree) =
2247 computeType (LTYPE (tree),
2251 /*------------------------------------------------------------------*/
2252 /*----------------------------*/
2253 /* address dereference */
2254 /*----------------------------*/
2255 case '*': /* can be unary : if right is null then unary operation */
2258 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2260 werror (E_PTR_REQD);
2261 goto errorTreeReturn;
2266 werror (E_LVALUE_REQUIRED, "pointer deref");
2267 goto errorTreeReturn;
2269 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2270 LTYPE (tree)->next : NULL);
2271 TETYPE (tree) = getSpec (TTYPE (tree));
2272 tree->args = tree->left->args;
2273 tree->hasVargs = tree->left->hasVargs;
2274 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2278 /*------------------------------------------------------------------*/
2279 /*----------------------------*/
2280 /* multiplication */
2281 /*----------------------------*/
2282 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2284 werror (E_INVALID_OP, "multiplication");
2285 goto errorTreeReturn;
2288 /* if they are both literal then */
2289 /* rewrite the tree */
2290 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2292 tree->type = EX_VALUE;
2293 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2294 valFromType (RETYPE (tree)));
2295 tree->right = tree->left = NULL;
2296 TETYPE (tree) = getSpec (TTYPE (tree) =
2297 tree->opval.val->type);
2301 /* if left is a literal exchange left & right */
2302 if (IS_LITERAL (LTYPE (tree)))
2304 ast *tTree = tree->left;
2305 tree->left = tree->right;
2306 tree->right = tTree;
2309 LRVAL (tree) = RRVAL (tree) = 1;
2310 /* promote result to int if left & right are char
2311 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2312 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2313 TETYPE (tree) = getSpec (TTYPE (tree) =
2314 computeType (LTYPE (tree),
2316 SPEC_NOUN(TETYPE(tree)) = V_INT;
2318 TETYPE (tree) = getSpec (TTYPE (tree) =
2319 computeType (LTYPE (tree),
2324 /*------------------------------------------------------------------*/
2325 /*----------------------------*/
2326 /* unary '+' operator */
2327 /*----------------------------*/
2332 if (!IS_INTEGRAL (LTYPE (tree)))
2334 werror (E_UNARY_OP, '+');
2335 goto errorTreeReturn;
2338 /* if left is a literal then do it */
2339 if (IS_LITERAL (LTYPE (tree)))
2341 tree->type = EX_VALUE;
2342 tree->opval.val = valFromType (LETYPE (tree));
2344 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2348 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2352 /*------------------------------------------------------------------*/
2353 /*----------------------------*/
2355 /*----------------------------*/
2357 /* this is not a unary operation */
2358 /* if both pointers then problem */
2359 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2360 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2362 werror (E_PTR_PLUS_PTR);
2363 goto errorTreeReturn;
2366 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2367 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2369 werror (E_PLUS_INVALID, "+");
2370 goto errorTreeReturn;
2373 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2374 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2376 werror (E_PLUS_INVALID, "+");
2377 goto errorTreeReturn;
2379 /* if they are both literal then */
2380 /* rewrite the tree */
2381 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2383 tree->type = EX_VALUE;
2384 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2385 valFromType (RETYPE (tree)));
2386 tree->right = tree->left = NULL;
2387 TETYPE (tree) = getSpec (TTYPE (tree) =
2388 tree->opval.val->type);
2392 /* if the right is a pointer or left is a literal
2393 xchange left & right */
2394 if (IS_ARRAY (RTYPE (tree)) ||
2395 IS_PTR (RTYPE (tree)) ||
2396 IS_LITERAL (LTYPE (tree)))
2398 ast *tTree = tree->left;
2399 tree->left = tree->right;
2400 tree->right = tTree;
2403 LRVAL (tree) = RRVAL (tree) = 1;
2404 /* if the left is a pointer */
2405 if (IS_PTR (LTYPE (tree)))
2406 TETYPE (tree) = getSpec (TTYPE (tree) =
2409 TETYPE (tree) = getSpec (TTYPE (tree) =
2410 computeType (LTYPE (tree),
2414 /*------------------------------------------------------------------*/
2415 /*----------------------------*/
2417 /*----------------------------*/
2418 case '-': /* can be unary */
2419 /* if right is null then unary */
2423 if (!IS_ARITHMETIC (LTYPE (tree)))
2425 werror (E_UNARY_OP, tree->opval.op);
2426 goto errorTreeReturn;
2429 /* if left is a literal then do it */
2430 if (IS_LITERAL (LTYPE (tree)))
2432 tree->type = EX_VALUE;
2433 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2435 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2436 SPEC_USIGN(TETYPE(tree)) = 0;
2440 TTYPE (tree) = LTYPE (tree);
2444 /*------------------------------------------------------------------*/
2445 /*----------------------------*/
2447 /*----------------------------*/
2449 if (!(IS_PTR (LTYPE (tree)) ||
2450 IS_ARRAY (LTYPE (tree)) ||
2451 IS_ARITHMETIC (LTYPE (tree))))
2453 werror (E_PLUS_INVALID, "-");
2454 goto errorTreeReturn;
2457 if (!(IS_PTR (RTYPE (tree)) ||
2458 IS_ARRAY (RTYPE (tree)) ||
2459 IS_ARITHMETIC (RTYPE (tree))))
2461 werror (E_PLUS_INVALID, "-");
2462 goto errorTreeReturn;
2465 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2466 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2467 IS_INTEGRAL (RTYPE (tree))))
2469 werror (E_PLUS_INVALID, "-");
2470 goto errorTreeReturn;
2473 /* if they are both literal then */
2474 /* rewrite the tree */
2475 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2477 tree->type = EX_VALUE;
2478 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2479 valFromType (RETYPE (tree)));
2480 tree->right = tree->left = NULL;
2481 TETYPE (tree) = getSpec (TTYPE (tree) =
2482 tree->opval.val->type);
2486 /* if the left & right are equal then zero */
2487 if (isAstEqual (tree->left, tree->right))
2489 tree->type = EX_VALUE;
2490 tree->left = tree->right = NULL;
2491 tree->opval.val = constVal ("0");
2492 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2496 /* if both of them are pointers or arrays then */
2497 /* the result is going to be an integer */
2498 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2499 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2500 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2502 /* if only the left is a pointer */
2503 /* then result is a pointer */
2504 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2505 TETYPE (tree) = getSpec (TTYPE (tree) =
2508 TETYPE (tree) = getSpec (TTYPE (tree) =
2509 computeType (LTYPE (tree),
2511 LRVAL (tree) = RRVAL (tree) = 1;
2514 /*------------------------------------------------------------------*/
2515 /*----------------------------*/
2517 /*----------------------------*/
2519 /* can be only integral type */
2520 if (!IS_INTEGRAL (LTYPE (tree)))
2522 werror (E_UNARY_OP, tree->opval.op);
2523 goto errorTreeReturn;
2526 /* if left is a literal then do it */
2527 if (IS_LITERAL (LTYPE (tree)))
2529 tree->type = EX_VALUE;
2530 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2532 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2536 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2539 /*------------------------------------------------------------------*/
2540 /*----------------------------*/
2542 /*----------------------------*/
2544 /* can be pointer */
2545 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2546 !IS_PTR (LTYPE (tree)) &&
2547 !IS_ARRAY (LTYPE (tree)))
2549 werror (E_UNARY_OP, tree->opval.op);
2550 goto errorTreeReturn;
2553 /* if left is a literal then do it */
2554 if (IS_LITERAL (LTYPE (tree)))
2556 tree->type = EX_VALUE;
2557 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2559 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2563 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2566 /*------------------------------------------------------------------*/
2567 /*----------------------------*/
2569 /*----------------------------*/
2572 TTYPE (tree) = LTYPE (tree);
2573 TETYPE (tree) = LETYPE (tree);
2577 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2582 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2584 werror (E_SHIFT_OP_INVALID);
2585 werror (E_CONTINUE, "left & right types are ");
2586 printTypeChain (LTYPE (tree), stderr);
2587 fprintf (stderr, ",");
2588 printTypeChain (RTYPE (tree), stderr);
2589 fprintf (stderr, "\n");
2590 goto errorTreeReturn;
2593 /* if they are both literal then */
2594 /* rewrite the tree */
2595 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2597 tree->type = EX_VALUE;
2598 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2599 valFromType (RETYPE (tree)),
2600 (tree->opval.op == LEFT_OP ? 1 : 0));
2601 tree->right = tree->left = NULL;
2602 TETYPE (tree) = getSpec (TTYPE (tree) =
2603 tree->opval.val->type);
2606 /* if only the right side is a literal & we are
2607 shifting more than size of the left operand then zero */
2608 if (IS_LITERAL (RTYPE (tree)) &&
2609 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2610 (getSize (LTYPE (tree)) * 8))
2612 werror (W_SHIFT_CHANGED,
2613 (tree->opval.op == LEFT_OP ? "left" : "right"));
2614 tree->type = EX_VALUE;
2615 tree->left = tree->right = NULL;
2616 tree->opval.val = constVal ("0");
2617 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2620 LRVAL (tree) = RRVAL (tree) = 1;
2621 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2623 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2627 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2631 /*------------------------------------------------------------------*/
2632 /*----------------------------*/
2634 /*----------------------------*/
2635 case CAST: /* change the type */
2636 /* cannot cast to an aggregate type */
2637 if (IS_AGGREGATE (LTYPE (tree)))
2639 werror (E_CAST_ILLEGAL);
2640 goto errorTreeReturn;
2643 /* make sure the type is complete and sane */
2644 checkTypeSanity(LETYPE(tree), "(cast)");
2646 /* if the right is a literal replace the tree */
2647 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2649 tree->type = EX_VALUE;
2651 valCastLiteral (LTYPE (tree),
2652 floatFromVal (valFromType (RETYPE (tree))));
2655 TTYPE (tree) = tree->opval.val->type;
2656 tree->values.literalFromCast = 1;
2660 TTYPE (tree) = LTYPE (tree);
2664 TETYPE (tree) = getSpec (TTYPE (tree));
2668 /*------------------------------------------------------------------*/
2669 /*----------------------------*/
2670 /* logical &&, || */
2671 /*----------------------------*/
2674 /* each must me arithmetic type or be a pointer */
2675 if (!IS_PTR (LTYPE (tree)) &&
2676 !IS_ARRAY (LTYPE (tree)) &&
2677 !IS_INTEGRAL (LTYPE (tree)))
2679 werror (E_COMPARE_OP);
2680 goto errorTreeReturn;
2683 if (!IS_PTR (RTYPE (tree)) &&
2684 !IS_ARRAY (RTYPE (tree)) &&
2685 !IS_INTEGRAL (RTYPE (tree)))
2687 werror (E_COMPARE_OP);
2688 goto errorTreeReturn;
2690 /* if they are both literal then */
2691 /* rewrite the tree */
2692 if (IS_LITERAL (RTYPE (tree)) &&
2693 IS_LITERAL (LTYPE (tree)))
2695 tree->type = EX_VALUE;
2696 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2697 valFromType (RETYPE (tree)),
2699 tree->right = tree->left = NULL;
2700 TETYPE (tree) = getSpec (TTYPE (tree) =
2701 tree->opval.val->type);
2704 LRVAL (tree) = RRVAL (tree) = 1;
2705 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2708 /*------------------------------------------------------------------*/
2709 /*----------------------------*/
2710 /* comparison operators */
2711 /*----------------------------*/
2719 ast *lt = optimizeCompare (tree);
2725 /* if they are pointers they must be castable */
2726 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2728 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2730 werror (E_COMPARE_OP);
2731 fprintf (stderr, "comparing type ");
2732 printTypeChain (LTYPE (tree), stderr);
2733 fprintf (stderr, "to type ");
2734 printTypeChain (RTYPE (tree), stderr);
2735 fprintf (stderr, "\n");
2736 goto errorTreeReturn;
2739 /* else they should be promotable to one another */
2742 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2743 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2745 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2747 werror (E_COMPARE_OP);
2748 fprintf (stderr, "comparing type ");
2749 printTypeChain (LTYPE (tree), stderr);
2750 fprintf (stderr, "to type ");
2751 printTypeChain (RTYPE (tree), stderr);
2752 fprintf (stderr, "\n");
2753 goto errorTreeReturn;
2757 /* if they are both literal then */
2758 /* rewrite the tree */
2759 if (IS_LITERAL (RTYPE (tree)) &&
2760 IS_LITERAL (LTYPE (tree)))
2762 tree->type = EX_VALUE;
2763 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2764 valFromType (RETYPE (tree)),
2766 tree->right = tree->left = NULL;
2767 TETYPE (tree) = getSpec (TTYPE (tree) =
2768 tree->opval.val->type);
2771 LRVAL (tree) = RRVAL (tree) = 1;
2772 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2775 /*------------------------------------------------------------------*/
2776 /*----------------------------*/
2778 /*----------------------------*/
2779 case SIZEOF: /* evaluate wihout code generation */
2780 /* change the type to a integer */
2781 tree->type = EX_VALUE;
2782 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2783 tree->opval.val = constVal (buffer);
2784 tree->right = tree->left = NULL;
2785 TETYPE (tree) = getSpec (TTYPE (tree) =
2786 tree->opval.val->type);
2789 /*------------------------------------------------------------------*/
2790 /*----------------------------*/
2791 /* conditional operator '?' */
2792 /*----------------------------*/
2794 /* the type is one on the left */
2795 TTYPE (tree) = LTYPE (tree);
2796 TETYPE (tree) = getSpec (TTYPE (tree));
2800 /* if they don't match we have a problem */
2801 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2803 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2804 goto errorTreeReturn;
2807 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2808 TETYPE (tree) = getSpec (TTYPE (tree));
2812 /*------------------------------------------------------------------*/
2813 /*----------------------------*/
2814 /* assignment operators */
2815 /*----------------------------*/
2818 /* for these it must be both must be integral */
2819 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2820 !IS_ARITHMETIC (RTYPE (tree)))
2822 werror (E_OPS_INTEGRAL);
2823 goto errorTreeReturn;
2826 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2828 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2829 werror (E_CODE_WRITE, " ");
2833 werror (E_LVALUE_REQUIRED, "*= or /=");
2834 goto errorTreeReturn;
2847 /* for these it must be both must be integral */
2848 if (!IS_INTEGRAL (LTYPE (tree)) ||
2849 !IS_INTEGRAL (RTYPE (tree)))
2851 werror (E_OPS_INTEGRAL);
2852 goto errorTreeReturn;
2855 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2857 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2858 werror (E_CODE_WRITE, " ");
2862 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2863 goto errorTreeReturn;
2871 /*------------------------------------------------------------------*/
2872 /*----------------------------*/
2874 /*----------------------------*/
2876 if (!(IS_PTR (LTYPE (tree)) ||
2877 IS_ARITHMETIC (LTYPE (tree))))
2879 werror (E_PLUS_INVALID, "-=");
2880 goto errorTreeReturn;
2883 if (!(IS_PTR (RTYPE (tree)) ||
2884 IS_ARITHMETIC (RTYPE (tree))))
2886 werror (E_PLUS_INVALID, "-=");
2887 goto errorTreeReturn;
2890 TETYPE (tree) = getSpec (TTYPE (tree) =
2891 computeType (LTYPE (tree),
2894 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2895 werror (E_CODE_WRITE, " ");
2899 werror (E_LVALUE_REQUIRED, "-=");
2900 goto errorTreeReturn;
2908 /*------------------------------------------------------------------*/
2909 /*----------------------------*/
2911 /*----------------------------*/
2913 /* this is not a unary operation */
2914 /* if both pointers then problem */
2915 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2917 werror (E_PTR_PLUS_PTR);
2918 goto errorTreeReturn;
2921 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2923 werror (E_PLUS_INVALID, "+=");
2924 goto errorTreeReturn;
2927 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2929 werror (E_PLUS_INVALID, "+=");
2930 goto errorTreeReturn;
2933 TETYPE (tree) = getSpec (TTYPE (tree) =
2934 computeType (LTYPE (tree),
2937 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2938 werror (E_CODE_WRITE, " ");
2942 werror (E_LVALUE_REQUIRED, "+=");
2943 goto errorTreeReturn;
2946 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2947 tree->opval.op = '=';
2953 /*------------------------------------------------------------------*/
2954 /*----------------------------*/
2955 /* straight assignemnt */
2956 /*----------------------------*/
2958 /* cannot be an aggregate */
2959 if (IS_AGGREGATE (LTYPE (tree)))
2961 werror (E_AGGR_ASSIGN);
2962 goto errorTreeReturn;
2965 /* they should either match or be castable */
2966 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2968 werror (E_TYPE_MISMATCH, "assignment", " ");
2969 fprintf (stderr, "type --> '");
2970 printTypeChain (RTYPE (tree), stderr);
2971 fprintf (stderr, "' ");
2972 fprintf (stderr, "assigned to type --> '");
2973 printTypeChain (LTYPE (tree), stderr);
2974 fprintf (stderr, "'\n");
2975 goto errorTreeReturn;
2978 /* if the left side of the tree is of type void
2979 then report error */
2980 if (IS_VOID (LTYPE (tree)))
2982 werror (E_CAST_ZERO);
2983 fprintf (stderr, "type --> '");
2984 printTypeChain (RTYPE (tree), stderr);
2985 fprintf (stderr, "' ");
2986 fprintf (stderr, "assigned to type --> '");
2987 printTypeChain (LTYPE (tree), stderr);
2988 fprintf (stderr, "'\n");
2991 /* extra checks for pointer types */
2992 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2993 !IS_GENPTR (LTYPE (tree)))
2995 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2996 werror (W_PTR_ASSIGN);
2999 TETYPE (tree) = getSpec (TTYPE (tree) =
3003 if (!tree->initMode ) {
3004 if (IS_CONSTANT (LETYPE (tree))) {
3005 werror (E_CODE_WRITE, " ");
3010 werror (E_LVALUE_REQUIRED, "=");
3011 goto errorTreeReturn;
3018 /*------------------------------------------------------------------*/
3019 /*----------------------------*/
3020 /* comma operator */
3021 /*----------------------------*/
3023 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3026 /*------------------------------------------------------------------*/
3027 /*----------------------------*/
3029 /*----------------------------*/
3033 if (processParms (tree->left,
3035 tree->right, &parmNumber, TRUE))
3036 goto errorTreeReturn;
3038 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3040 tree->left->args = reverseVal (tree->left->args);
3041 reverseParms (tree->right);
3044 tree->args = tree->left->args;
3045 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3048 /*------------------------------------------------------------------*/
3049 /*----------------------------*/
3050 /* return statement */
3051 /*----------------------------*/
3056 if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3058 werror (E_RETURN_MISMATCH);
3059 goto errorTreeReturn;
3062 if (IS_VOID (currFunc->type->next)
3064 !IS_VOID (RTYPE (tree)))
3066 werror (E_FUNC_VOID);
3067 goto errorTreeReturn;
3070 /* if there is going to be a casing required then add it */
3071 if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3073 #if 0 && defined DEMAND_INTEGER_PROMOTION
3074 if (IS_INTEGRAL (currFunc->type->next))
3076 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3082 decorateType (newNode (CAST,
3083 newAst_LINK (copyLinkChain (currFunc->type->next)),
3093 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3095 werror (E_VOID_FUNC, currFunc->name);
3096 goto errorTreeReturn;
3099 TTYPE (tree) = TETYPE (tree) = NULL;
3102 /*------------------------------------------------------------------*/
3103 /*----------------------------*/
3104 /* switch statement */
3105 /*----------------------------*/
3107 /* the switch value must be an integer */
3108 if (!IS_INTEGRAL (LTYPE (tree)))
3110 werror (E_SWITCH_NON_INTEGER);
3111 goto errorTreeReturn;
3114 TTYPE (tree) = TETYPE (tree) = NULL;
3117 /*------------------------------------------------------------------*/
3118 /*----------------------------*/
3120 /*----------------------------*/
3122 tree->left = backPatchLabels (tree->left,
3125 TTYPE (tree) = TETYPE (tree) = NULL;
3128 /*------------------------------------------------------------------*/
3129 /*----------------------------*/
3131 /*----------------------------*/
3134 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3135 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3136 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3138 /* if the for loop is reversible then
3139 reverse it otherwise do what we normally
3145 if (isLoopReversible (tree, &sym, &init, &end))
3146 return reverseLoop (tree, sym, init, end);
3148 return decorateType (createFor (AST_FOR (tree, trueLabel),
3149 AST_FOR (tree, continueLabel),
3150 AST_FOR (tree, falseLabel),
3151 AST_FOR (tree, condLabel),
3152 AST_FOR (tree, initExpr),
3153 AST_FOR (tree, condExpr),
3154 AST_FOR (tree, loopExpr),
3158 TTYPE (tree) = TETYPE (tree) = NULL;
3162 /* some error found this tree will be killed */
3164 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3165 tree->opval.op = NULLOP;
3171 /*-----------------------------------------------------------------*/
3172 /* sizeofOp - processes size of operation */
3173 /*-----------------------------------------------------------------*/
3175 sizeofOp (sym_link * type)
3179 /* make sure the type is complete and sane */
3180 checkTypeSanity(type, "(sizeof)");
3182 /* get the size and convert it to character */
3183 sprintf (buff, "%d", getSize (type));
3185 /* now convert into value */
3186 return constVal (buff);
3190 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3191 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3192 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3193 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3194 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3195 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3196 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3198 /*-----------------------------------------------------------------*/
3199 /* backPatchLabels - change and or not operators to flow control */
3200 /*-----------------------------------------------------------------*/
3202 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3208 if (!(IS_ANDORNOT (tree)))
3211 /* if this an and */
3214 static int localLbl = 0;
3217 sprintf (buffer, "_and_%d", localLbl++);
3218 localLabel = newSymbol (buffer, NestLevel);
3220 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3222 /* if left is already a IFX then just change the if true label in that */
3223 if (!IS_IFX (tree->left))
3224 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3226 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3227 /* right is a IFX then just join */
3228 if (IS_IFX (tree->right))
3229 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3231 tree->right = createLabel (localLabel, tree->right);
3232 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3234 return newNode (NULLOP, tree->left, tree->right);
3237 /* if this is an or operation */
3240 static int localLbl = 0;
3243 sprintf (buffer, "_or_%d", localLbl++);
3244 localLabel = newSymbol (buffer, NestLevel);
3246 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3248 /* if left is already a IFX then just change the if true label in that */
3249 if (!IS_IFX (tree->left))
3250 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3252 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3253 /* right is a IFX then just join */
3254 if (IS_IFX (tree->right))
3255 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3257 tree->right = createLabel (localLabel, tree->right);
3258 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3260 return newNode (NULLOP, tree->left, tree->right);
3266 int wasnot = IS_NOT (tree->left);
3267 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3269 /* if the left is already a IFX */
3270 if (!IS_IFX (tree->left))
3271 tree->left = newNode (IFX, tree->left, NULL);
3275 tree->left->trueLabel = trueLabel;
3276 tree->left->falseLabel = falseLabel;
3280 tree->left->trueLabel = falseLabel;
3281 tree->left->falseLabel = trueLabel;
3288 tree->trueLabel = trueLabel;
3289 tree->falseLabel = falseLabel;
3296 /*-----------------------------------------------------------------*/
3297 /* createBlock - create expression tree for block */
3298 /*-----------------------------------------------------------------*/
3300 createBlock (symbol * decl, ast * body)
3304 /* if the block has nothing */
3308 ex = newNode (BLOCK, NULL, body);
3309 ex->values.sym = decl;
3311 ex->right = ex->right;
3317 /*-----------------------------------------------------------------*/
3318 /* createLabel - creates the expression tree for labels */
3319 /*-----------------------------------------------------------------*/
3321 createLabel (symbol * label, ast * stmnt)
3324 char name[SDCC_NAME_MAX + 1];
3327 /* must create fresh symbol if the symbol name */
3328 /* exists in the symbol table, since there can */
3329 /* be a variable with the same name as the labl */
3330 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3331 (csym->level == label->level))
3332 label = newSymbol (label->name, label->level);
3334 /* change the name before putting it in add _ */
3335 sprintf (name, "%s", label->name);
3337 /* put the label in the LabelSymbol table */
3338 /* but first check if a label of the same */
3340 if ((csym = findSym (LabelTab, NULL, name)))
3341 werror (E_DUPLICATE_LABEL, label->name);
3343 addSym (LabelTab, label, name, label->level, 0, 0);
3346 label->key = labelKey++;
3347 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3353 /*-----------------------------------------------------------------*/
3354 /* createCase - generates the parsetree for a case statement */
3355 /*-----------------------------------------------------------------*/
3357 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3359 char caseLbl[SDCC_NAME_MAX + 1];
3363 /* if the switch statement does not exist */
3364 /* then case is out of context */
3367 werror (E_CASE_CONTEXT);
3371 caseVal = decorateType (resolveSymbols (caseVal));
3372 /* if not a constant then error */
3373 if (!IS_LITERAL (caseVal->ftype))
3375 werror (E_CASE_CONSTANT);
3379 /* if not a integer than error */
3380 if (!IS_INTEGRAL (caseVal->ftype))
3382 werror (E_CASE_NON_INTEGER);
3386 /* find the end of the switch values chain */
3387 if (!(val = swStat->values.switchVals.swVals))
3388 swStat->values.switchVals.swVals = caseVal->opval.val;
3391 /* also order the cases according to value */
3393 int cVal = (int) floatFromVal (caseVal->opval.val);
3394 while (val && (int) floatFromVal (val) < cVal)
3400 /* if we reached the end then */
3403 pval->next = caseVal->opval.val;
3407 /* we found a value greater than */
3408 /* the current value we must add this */
3409 /* before the value */
3410 caseVal->opval.val->next = val;
3412 /* if this was the first in chain */
3413 if (swStat->values.switchVals.swVals == val)
3414 swStat->values.switchVals.swVals =
3417 pval->next = caseVal->opval.val;
3422 /* create the case label */
3423 sprintf (caseLbl, "_case_%d_%d",
3424 swStat->values.switchVals.swNum,
3425 (int) floatFromVal (caseVal->opval.val));
3427 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3432 /*-----------------------------------------------------------------*/
3433 /* createDefault - creates the parse tree for the default statement */
3434 /*-----------------------------------------------------------------*/
3436 createDefault (ast * swStat, ast * stmnt)
3438 char defLbl[SDCC_NAME_MAX + 1];
3440 /* if the switch statement does not exist */
3441 /* then case is out of context */
3444 werror (E_CASE_CONTEXT);
3448 /* turn on the default flag */
3449 swStat->values.switchVals.swDefault = 1;
3451 /* create the label */
3452 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3453 return createLabel (newSymbol (defLbl, 0), stmnt);
3456 /*-----------------------------------------------------------------*/
3457 /* createIf - creates the parsetree for the if statement */
3458 /*-----------------------------------------------------------------*/
3460 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3462 static int Lblnum = 0;
3464 symbol *ifTrue, *ifFalse, *ifEnd;
3466 /* if neither exists */
3467 if (!elseBody && !ifBody)
3470 /* create the labels */
3471 sprintf (buffer, "_iffalse_%d", Lblnum);
3472 ifFalse = newSymbol (buffer, NestLevel);
3473 /* if no else body then end == false */
3478 sprintf (buffer, "_ifend_%d", Lblnum);
3479 ifEnd = newSymbol (buffer, NestLevel);
3482 sprintf (buffer, "_iftrue_%d", Lblnum);
3483 ifTrue = newSymbol (buffer, NestLevel);
3487 /* attach the ifTrue label to the top of it body */
3488 ifBody = createLabel (ifTrue, ifBody);
3489 /* attach a goto end to the ifBody if else is present */
3492 ifBody = newNode (NULLOP, ifBody,
3494 newAst_VALUE (symbolVal (ifEnd)),
3496 /* put the elseLabel on the else body */
3497 elseBody = createLabel (ifFalse, elseBody);
3498 /* out the end at the end of the body */
3499 elseBody = newNode (NULLOP,
3501 createLabel (ifEnd, NULL));
3505 ifBody = newNode (NULLOP, ifBody,
3506 createLabel (ifFalse, NULL));
3508 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3509 if (IS_IFX (condAst))
3512 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3514 return newNode (NULLOP, ifTree,
3515 newNode (NULLOP, ifBody, elseBody));
3519 /*-----------------------------------------------------------------*/
3520 /* createDo - creates parse tree for do */
3523 /* _docontinue_n: */
3524 /* condition_expression +-> trueLabel -> _dobody_n */
3526 /* +-> falseLabel-> _dobreak_n */
3528 /*-----------------------------------------------------------------*/
3530 createDo (symbol * trueLabel, symbol * continueLabel,
3531 symbol * falseLabel, ast * condAst, ast * doBody)
3536 /* if the body does not exist then it is simple */
3539 condAst = backPatchLabels (condAst, continueLabel, NULL);
3540 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3541 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3542 doTree->trueLabel = continueLabel;
3543 doTree->falseLabel = NULL;
3547 /* otherwise we have a body */
3548 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3550 /* attach the body label to the top */
3551 doBody = createLabel (trueLabel, doBody);
3552 /* attach the continue label to end of body */
3553 doBody = newNode (NULLOP, doBody,
3554 createLabel (continueLabel, NULL));
3556 /* now put the break label at the end */
3557 if (IS_IFX (condAst))
3560 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3562 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3564 /* putting it together */
3565 return newNode (NULLOP, doBody, doTree);
3568 /*-----------------------------------------------------------------*/
3569 /* createFor - creates parse tree for 'for' statement */
3572 /* condExpr +-> trueLabel -> _forbody_n */
3574 /* +-> falseLabel-> _forbreak_n */
3577 /* _forcontinue_n: */
3579 /* goto _forcond_n ; */
3581 /*-----------------------------------------------------------------*/
3583 createFor (symbol * trueLabel, symbol * continueLabel,
3584 symbol * falseLabel, symbol * condLabel,
3585 ast * initExpr, ast * condExpr, ast * loopExpr,
3590 /* if loopexpression not present then we can generate it */
3591 /* the same way as a while */
3593 return newNode (NULLOP, initExpr,
3594 createWhile (trueLabel, continueLabel,
3595 falseLabel, condExpr, forBody));
3596 /* vanilla for statement */
3597 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3599 if (condExpr && !IS_IFX (condExpr))
3600 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3603 /* attach condition label to condition */
3604 condExpr = createLabel (condLabel, condExpr);
3606 /* attach body label to body */
3607 forBody = createLabel (trueLabel, forBody);
3609 /* attach continue to forLoop expression & attach */
3610 /* goto the forcond @ and of loopExpression */
3611 loopExpr = createLabel (continueLabel,
3615 newAst_VALUE (symbolVal (condLabel)),
3617 /* now start putting them together */
3618 forTree = newNode (NULLOP, initExpr, condExpr);
3619 forTree = newNode (NULLOP, forTree, forBody);
3620 forTree = newNode (NULLOP, forTree, loopExpr);
3621 /* finally add the break label */
3622 forTree = newNode (NULLOP, forTree,
3623 createLabel (falseLabel, NULL));
3627 /*-----------------------------------------------------------------*/
3628 /* createWhile - creates parse tree for while statement */
3629 /* the while statement will be created as follows */
3631 /* _while_continue_n: */
3632 /* condition_expression +-> trueLabel -> _while_boby_n */
3634 /* +-> falseLabel -> _while_break_n */
3635 /* _while_body_n: */
3637 /* goto _while_continue_n */
3638 /* _while_break_n: */
3639 /*-----------------------------------------------------------------*/
3641 createWhile (symbol * trueLabel, symbol * continueLabel,
3642 symbol * falseLabel, ast * condExpr, ast * whileBody)
3646 /* put the continue label */
3647 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3648 condExpr = createLabel (continueLabel, condExpr);
3649 condExpr->lineno = 0;
3651 /* put the body label in front of the body */
3652 whileBody = createLabel (trueLabel, whileBody);
3653 whileBody->lineno = 0;
3654 /* put a jump to continue at the end of the body */
3655 /* and put break label at the end of the body */
3656 whileBody = newNode (NULLOP,
3659 newAst_VALUE (symbolVal (continueLabel)),
3660 createLabel (falseLabel, NULL)));
3662 /* put it all together */
3663 if (IS_IFX (condExpr))
3664 whileTree = condExpr;
3667 whileTree = newNode (IFX, condExpr, NULL);
3668 /* put the true & false labels in place */
3669 whileTree->trueLabel = trueLabel;
3670 whileTree->falseLabel = falseLabel;
3673 return newNode (NULLOP, whileTree, whileBody);
3676 /*-----------------------------------------------------------------*/
3677 /* optimizeGetHbit - get highest order bit of the expression */
3678 /*-----------------------------------------------------------------*/
3680 optimizeGetHbit (ast * tree)
3683 /* if this is not a bit and */
3684 if (!IS_BITAND (tree))
3687 /* will look for tree of the form
3688 ( expr >> ((sizeof expr) -1) ) & 1 */
3689 if (!IS_AST_LIT_VALUE (tree->right))
3692 if (AST_LIT_VALUE (tree->right) != 1)
3695 if (!IS_RIGHT_OP (tree->left))
3698 if (!IS_AST_LIT_VALUE (tree->left->right))
3701 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3702 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3705 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3709 /*-----------------------------------------------------------------*/
3710 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3711 /*-----------------------------------------------------------------*/
3713 optimizeRRCRLC (ast * root)
3715 /* will look for trees of the form
3716 (?expr << 1) | (?expr >> 7) or
3717 (?expr >> 7) | (?expr << 1) will make that
3718 into a RLC : operation ..
3720 (?expr >> 1) | (?expr << 7) or
3721 (?expr << 7) | (?expr >> 1) will make that
3722 into a RRC operation
3723 note : by 7 I mean (number of bits required to hold the
3725 /* if the root operations is not a | operation the not */
3726 if (!IS_BITOR (root))
3729 /* I have to think of a better way to match patterns this sucks */
3730 /* that aside let start looking for the first case : I use a the
3731 negative check a lot to improve the efficiency */
3732 /* (?expr << 1) | (?expr >> 7) */
3733 if (IS_LEFT_OP (root->left) &&
3734 IS_RIGHT_OP (root->right))
3737 if (!SPEC_USIGN (TETYPE (root->left->left)))
3740 if (!IS_AST_LIT_VALUE (root->left->right) ||
3741 !IS_AST_LIT_VALUE (root->right->right))
3744 /* make sure it is the same expression */
3745 if (!isAstEqual (root->left->left,
3749 if (AST_LIT_VALUE (root->left->right) != 1)
3752 if (AST_LIT_VALUE (root->right->right) !=
3753 (getSize (TTYPE (root->left->left)) * 8 - 1))
3756 /* whew got the first case : create the AST */
3757 return newNode (RLC, root->left->left, NULL);
3761 /* check for second case */
3762 /* (?expr >> 7) | (?expr << 1) */
3763 if (IS_LEFT_OP (root->right) &&
3764 IS_RIGHT_OP (root->left))
3767 if (!SPEC_USIGN (TETYPE (root->left->left)))
3770 if (!IS_AST_LIT_VALUE (root->left->right) ||
3771 !IS_AST_LIT_VALUE (root->right->right))
3774 /* make sure it is the same symbol */
3775 if (!isAstEqual (root->left->left,
3779 if (AST_LIT_VALUE (root->right->right) != 1)
3782 if (AST_LIT_VALUE (root->left->right) !=
3783 (getSize (TTYPE (root->left->left)) * 8 - 1))
3786 /* whew got the first case : create the AST */
3787 return newNode (RLC, root->left->left, NULL);
3792 /* third case for RRC */
3793 /* (?symbol >> 1) | (?symbol << 7) */
3794 if (IS_LEFT_OP (root->right) &&
3795 IS_RIGHT_OP (root->left))
3798 if (!SPEC_USIGN (TETYPE (root->left->left)))
3801 if (!IS_AST_LIT_VALUE (root->left->right) ||
3802 !IS_AST_LIT_VALUE (root->right->right))
3805 /* make sure it is the same symbol */
3806 if (!isAstEqual (root->left->left,
3810 if (AST_LIT_VALUE (root->left->right) != 1)
3813 if (AST_LIT_VALUE (root->right->right) !=
3814 (getSize (TTYPE (root->left->left)) * 8 - 1))
3817 /* whew got the first case : create the AST */
3818 return newNode (RRC, root->left->left, NULL);
3822 /* fourth and last case for now */
3823 /* (?symbol << 7) | (?symbol >> 1) */
3824 if (IS_RIGHT_OP (root->right) &&
3825 IS_LEFT_OP (root->left))
3828 if (!SPEC_USIGN (TETYPE (root->left->left)))
3831 if (!IS_AST_LIT_VALUE (root->left->right) ||
3832 !IS_AST_LIT_VALUE (root->right->right))
3835 /* make sure it is the same symbol */
3836 if (!isAstEqual (root->left->left,
3840 if (AST_LIT_VALUE (root->right->right) != 1)
3843 if (AST_LIT_VALUE (root->left->right) !=
3844 (getSize (TTYPE (root->left->left)) * 8 - 1))
3847 /* whew got the first case : create the AST */
3848 return newNode (RRC, root->left->left, NULL);
3852 /* not found return root */
3856 /*-----------------------------------------------------------------*/
3857 /* optimizeCompare - otimizes compares for bit variables */
3858 /*-----------------------------------------------------------------*/
3860 optimizeCompare (ast * root)
3862 ast *optExpr = NULL;
3865 unsigned int litValue;
3867 /* if nothing then return nothing */
3871 /* if not a compare op then do leaves */
3872 if (!IS_COMPARE_OP (root))
3874 root->left = optimizeCompare (root->left);
3875 root->right = optimizeCompare (root->right);
3879 /* if left & right are the same then depending
3880 of the operation do */
3881 if (isAstEqual (root->left, root->right))
3883 switch (root->opval.op)
3888 optExpr = newAst_VALUE (constVal ("0"));
3893 optExpr = newAst_VALUE (constVal ("1"));
3897 return decorateType (optExpr);
3900 vleft = (root->left->type == EX_VALUE ?
3901 root->left->opval.val : NULL);
3903 vright = (root->right->type == EX_VALUE ?
3904 root->right->opval.val : NULL);
3906 /* if left is a BITVAR in BITSPACE */
3907 /* and right is a LITERAL then opt- */
3908 /* imize else do nothing */
3909 if (vleft && vright &&
3910 IS_BITVAR (vleft->etype) &&
3911 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3912 IS_LITERAL (vright->etype))
3915 /* if right side > 1 then comparison may never succeed */
3916 if ((litValue = (int) floatFromVal (vright)) > 1)
3918 werror (W_BAD_COMPARE);
3924 switch (root->opval.op)
3926 case '>': /* bit value greater than 1 cannot be */
3927 werror (W_BAD_COMPARE);
3931 case '<': /* bit value < 1 means 0 */
3933 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3936 case LE_OP: /* bit value <= 1 means no check */
3937 optExpr = newAst_VALUE (vright);
3940 case GE_OP: /* bit value >= 1 means only check for = */
3942 optExpr = newAst_VALUE (vleft);
3947 { /* literal is zero */
3948 switch (root->opval.op)
3950 case '<': /* bit value < 0 cannot be */
3951 werror (W_BAD_COMPARE);
3955 case '>': /* bit value > 0 means 1 */
3957 optExpr = newAst_VALUE (vleft);
3960 case LE_OP: /* bit value <= 0 means no check */
3961 case GE_OP: /* bit value >= 0 means no check */
3962 werror (W_BAD_COMPARE);
3966 case EQ_OP: /* bit == 0 means ! of bit */
3967 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3971 return decorateType (resolveSymbols (optExpr));
3972 } /* end-of-if of BITVAR */
3977 /*-----------------------------------------------------------------*/
3978 /* addSymToBlock : adds the symbol to the first block we find */
3979 /*-----------------------------------------------------------------*/
3981 addSymToBlock (symbol * sym, ast * tree)
3983 /* reached end of tree or a leaf */
3984 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3988 if (IS_AST_OP (tree) &&
3989 tree->opval.op == BLOCK)
3992 symbol *lsym = copySymbol (sym);
3994 lsym->next = AST_VALUES (tree, sym);
3995 AST_VALUES (tree, sym) = lsym;
3999 addSymToBlock (sym, tree->left);
4000 addSymToBlock (sym, tree->right);
4003 /*-----------------------------------------------------------------*/
4004 /* processRegParms - do processing for register parameters */
4005 /*-----------------------------------------------------------------*/
4007 processRegParms (value * args, ast * body)
4011 if (IS_REGPARM (args->etype))
4012 addSymToBlock (args->sym, body);
4017 /*-----------------------------------------------------------------*/
4018 /* resetParmKey - resets the operandkeys for the symbols */
4019 /*-----------------------------------------------------------------*/
4020 DEFSETFUNC (resetParmKey)
4031 /*-----------------------------------------------------------------*/
4032 /* createFunction - This is the key node that calls the iCode for */
4033 /* generating the code for a function. Note code */
4034 /* is generated function by function, later when */
4035 /* add inter-procedural analysis this will change */
4036 /*-----------------------------------------------------------------*/
4038 createFunction (symbol * name, ast * body)
4044 iCode *piCode = NULL;
4046 /* if check function return 0 then some problem */
4047 if (checkFunction (name) == 0)
4050 /* create a dummy block if none exists */
4052 body = newNode (BLOCK, NULL, NULL);
4056 /* check if the function name already in the symbol table */
4057 if ((csym = findSym (SymbolTab, NULL, name->name)))
4060 /* special case for compiler defined functions
4061 we need to add the name to the publics list : this
4062 actually means we are now compiling the compiler
4066 addSet (&publics, name);
4072 allocVariables (name);
4074 name->lastLine = yylineno;
4076 processFuncArgs (currFunc, 0);
4078 /* set the stack pointer */
4079 /* PENDING: check this for the mcs51 */
4080 stackPtr = -port->stack.direction * port->stack.call_overhead;
4081 if (IS_ISR (name->etype))
4082 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4083 if (IS_RENT (name->etype) || options.stackAuto)
4084 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4086 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4088 fetype = getSpec (name->type); /* get the specifier for the function */
4089 /* if this is a reentrant function then */
4090 if (IS_RENT (fetype))
4093 allocParms (name->args); /* allocate the parameters */
4095 /* do processing for parameters that are passed in registers */
4096 processRegParms (name->args, body);
4098 /* set the stack pointer */
4102 /* allocate & autoinit the block variables */
4103 processBlockVars (body, &stack, ALLOCATE);
4105 /* save the stack information */
4106 if (options.useXstack)
4107 name->xstack = SPEC_STAK (fetype) = stack;
4109 name->stack = SPEC_STAK (fetype) = stack;
4111 /* name needs to be mangled */
4112 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4114 body = resolveSymbols (body); /* resolve the symbols */
4115 body = decorateType (body); /* propagateType & do semantic checks */
4117 ex = newAst_VALUE (symbolVal (name)); /* create name */
4118 ex = newNode (FUNCTION, ex, body);
4119 ex->values.args = name->args;
4123 werror (E_FUNC_NO_CODE, name->name);
4127 /* create the node & generate intermediate code */
4129 codeOutFile = code->oFile;
4130 piCode = iCodeFromAst (ex);
4134 werror (E_FUNC_NO_CODE, name->name);
4138 eBBlockFromiCode (piCode);
4140 /* if there are any statics then do them */
4143 GcurMemmap = statsg;
4144 codeOutFile = statsg->oFile;
4145 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4151 /* dealloc the block variables */
4152 processBlockVars (body, &stack, DEALLOCATE);
4153 /* deallocate paramaters */
4154 deallocParms (name->args);
4156 if (IS_RENT (fetype))
4159 /* we are done freeup memory & cleanup */
4164 addSet (&operKeyReset, name);
4165 applyToSet (operKeyReset, resetParmKey);
4167 if (options.debug && !options.nodebug)
4168 cdbStructBlock (1, cdbFile);
4170 cleanUpLevel (LabelTab, 0);
4171 cleanUpBlock (StructTab, 1);
4172 cleanUpBlock (TypedefTab, 1);
4174 xstack->syms = NULL;
4175 istack->syms = NULL;
4180 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4181 /*-----------------------------------------------------------------*/
4182 /* ast_print : prints the ast (for debugging purposes) */
4183 /*-----------------------------------------------------------------*/
4185 void ast_print (ast * tree, FILE *outfile, int indent)
4190 /* can print only decorated trees */
4191 if (!tree->decorated) return;
4193 /* if any child is an error | this one is an error do nothing */
4194 if (tree->isError ||
4195 (tree->left && tree->left->isError) ||
4196 (tree->right && tree->right->isError)) {
4197 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4201 /* print the line */
4202 /* if not block & function */
4203 if (tree->type == EX_OP &&
4204 (tree->opval.op != FUNCTION &&
4205 tree->opval.op != BLOCK &&
4206 tree->opval.op != NULLOP)) {
4209 if (tree->opval.op == FUNCTION) {
4210 fprintf(outfile,"FUNCTION (%p) type (",tree);
4211 printTypeChain (tree->ftype,outfile);
4212 fprintf(outfile,")\n");
4213 ast_print(tree->left,outfile,indent+4);
4214 ast_print(tree->right,outfile,indent+4);
4217 if (tree->opval.op == BLOCK) {
4218 symbol *decls = tree->values.sym;
4219 fprintf(outfile,"{\n");
4221 INDENT(indent+4,outfile);
4222 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4223 printTypeChain(decls->type,outfile);
4224 fprintf(outfile,")\n");
4226 decls = decls->next;
4228 ast_print(tree->right,outfile,indent+4);
4229 fprintf(outfile,"}\n");
4232 if (tree->opval.op == NULLOP) {
4233 fprintf(outfile,"\n");
4234 ast_print(tree->left,outfile,indent);
4235 fprintf(outfile,"\n");
4236 ast_print(tree->right,outfile,indent);
4239 INDENT(indent,outfile);
4241 /*------------------------------------------------------------------*/
4242 /*----------------------------*/
4243 /* leaf has been reached */
4244 /*----------------------------*/
4245 /* if this is of type value */
4246 /* just get the type */
4247 if (tree->type == EX_VALUE) {
4249 if (IS_LITERAL (tree->opval.val->etype)) {
4250 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4251 (int) floatFromVal(tree->opval.val),
4252 (int) floatFromVal(tree->opval.val),
4253 floatFromVal(tree->opval.val));
4254 } else if (tree->opval.val->sym) {
4255 /* if the undefined flag is set then give error message */
4256 if (tree->opval.val->sym->undefined) {
4257 fprintf(outfile,"UNDEFINED SYMBOL ");
4259 fprintf(outfile,"SYMBOL ");
4261 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4264 fprintf(outfile," type (");
4265 printTypeChain(tree->ftype,outfile);
4266 fprintf(outfile,")\n");
4268 fprintf(outfile,"\n");
4273 /* if type link for the case of cast */
4274 if (tree->type == EX_LINK) {
4275 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4276 printTypeChain(tree->opval.lnk,outfile);
4277 fprintf(outfile,")\n");
4282 /* depending on type of operator do */
4284 switch (tree->opval.op) {
4285 /*------------------------------------------------------------------*/
4286 /*----------------------------*/
4288 /*----------------------------*/
4290 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4291 printTypeChain(tree->ftype,outfile);
4292 fprintf(outfile,")\n");
4293 ast_print(tree->left,outfile,indent+4);
4294 ast_print(tree->right,outfile,indent+4);
4297 /*------------------------------------------------------------------*/
4298 /*----------------------------*/
4300 /*----------------------------*/
4302 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4303 printTypeChain(tree->ftype,outfile);
4304 fprintf(outfile,")\n");
4305 ast_print(tree->left,outfile,indent+4);
4306 ast_print(tree->right,outfile,indent+4);
4309 /*------------------------------------------------------------------*/
4310 /*----------------------------*/
4311 /* struct/union pointer */
4312 /*----------------------------*/
4314 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4315 printTypeChain(tree->ftype,outfile);
4316 fprintf(outfile,")\n");
4317 ast_print(tree->left,outfile,indent+4);
4318 ast_print(tree->right,outfile,indent+4);
4321 /*------------------------------------------------------------------*/
4322 /*----------------------------*/
4323 /* ++/-- operation */
4324 /*----------------------------*/
4325 case INC_OP: /* incerement operator unary so left only */
4326 fprintf(outfile,"INC_OP (%p) type (",tree);
4327 printTypeChain(tree->ftype,outfile);
4328 fprintf(outfile,")\n");
4329 ast_print(tree->left,outfile,indent+4);
4333 fprintf(outfile,"DEC_OP (%p) type (",tree);
4334 printTypeChain(tree->ftype,outfile);
4335 fprintf(outfile,")\n");
4336 ast_print(tree->left,outfile,indent+4);
4339 /*------------------------------------------------------------------*/
4340 /*----------------------------*/
4342 /*----------------------------*/
4345 fprintf(outfile,"& (%p) type (",tree);
4346 printTypeChain(tree->ftype,outfile);
4347 fprintf(outfile,")\n");
4348 ast_print(tree->left,outfile,indent+4);
4349 ast_print(tree->right,outfile,indent+4);
4351 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4352 printTypeChain(tree->ftype,outfile);
4353 fprintf(outfile,")\n");
4354 ast_print(tree->left,outfile,indent+4);
4355 ast_print(tree->right,outfile,indent+4);
4358 /*----------------------------*/
4360 /*----------------------------*/
4362 fprintf(outfile,"OR (%p) type (",tree);
4363 printTypeChain(tree->ftype,outfile);
4364 fprintf(outfile,")\n");
4365 ast_print(tree->left,outfile,indent+4);
4366 ast_print(tree->right,outfile,indent+4);
4368 /*------------------------------------------------------------------*/
4369 /*----------------------------*/
4371 /*----------------------------*/
4373 fprintf(outfile,"XOR (%p) type (",tree);
4374 printTypeChain(tree->ftype,outfile);
4375 fprintf(outfile,")\n");
4376 ast_print(tree->left,outfile,indent+4);
4377 ast_print(tree->right,outfile,indent+4);
4380 /*------------------------------------------------------------------*/
4381 /*----------------------------*/
4383 /*----------------------------*/
4385 fprintf(outfile,"DIV (%p) type (",tree);
4386 printTypeChain(tree->ftype,outfile);
4387 fprintf(outfile,")\n");
4388 ast_print(tree->left,outfile,indent+4);
4389 ast_print(tree->right,outfile,indent+4);
4391 /*------------------------------------------------------------------*/
4392 /*----------------------------*/
4394 /*----------------------------*/
4396 fprintf(outfile,"MOD (%p) type (",tree);
4397 printTypeChain(tree->ftype,outfile);
4398 fprintf(outfile,")\n");
4399 ast_print(tree->left,outfile,indent+4);
4400 ast_print(tree->right,outfile,indent+4);
4403 /*------------------------------------------------------------------*/
4404 /*----------------------------*/
4405 /* address dereference */
4406 /*----------------------------*/
4407 case '*': /* can be unary : if right is null then unary operation */
4409 fprintf(outfile,"DEREF (%p) type (",tree);
4410 printTypeChain(tree->ftype,outfile);
4411 fprintf(outfile,")\n");
4412 ast_print(tree->left,outfile,indent+4);
4415 /*------------------------------------------------------------------*/
4416 /*----------------------------*/
4417 /* multiplication */
4418 /*----------------------------*/
4419 fprintf(outfile,"MULT (%p) type (",tree);
4420 printTypeChain(tree->ftype,outfile);
4421 fprintf(outfile,")\n");
4422 ast_print(tree->left,outfile,indent+4);
4423 ast_print(tree->right,outfile,indent+4);
4427 /*------------------------------------------------------------------*/
4428 /*----------------------------*/
4429 /* unary '+' operator */
4430 /*----------------------------*/
4434 fprintf(outfile,"UPLUS (%p) type (",tree);
4435 printTypeChain(tree->ftype,outfile);
4436 fprintf(outfile,")\n");
4437 ast_print(tree->left,outfile,indent+4);
4439 /*------------------------------------------------------------------*/
4440 /*----------------------------*/
4442 /*----------------------------*/
4443 fprintf(outfile,"ADD (%p) type (",tree);
4444 printTypeChain(tree->ftype,outfile);
4445 fprintf(outfile,")\n");
4446 ast_print(tree->left,outfile,indent+4);
4447 ast_print(tree->right,outfile,indent+4);
4450 /*------------------------------------------------------------------*/
4451 /*----------------------------*/
4453 /*----------------------------*/
4454 case '-': /* can be unary */
4456 fprintf(outfile,"UMINUS (%p) type (",tree);
4457 printTypeChain(tree->ftype,outfile);
4458 fprintf(outfile,")\n");
4459 ast_print(tree->left,outfile,indent+4);
4461 /*------------------------------------------------------------------*/
4462 /*----------------------------*/
4464 /*----------------------------*/
4465 fprintf(outfile,"SUB (%p) type (",tree);
4466 printTypeChain(tree->ftype,outfile);
4467 fprintf(outfile,")\n");
4468 ast_print(tree->left,outfile,indent+4);
4469 ast_print(tree->right,outfile,indent+4);
4472 /*------------------------------------------------------------------*/
4473 /*----------------------------*/
4475 /*----------------------------*/
4477 fprintf(outfile,"COMPL (%p) type (",tree);
4478 printTypeChain(tree->ftype,outfile);
4479 fprintf(outfile,")\n");
4480 ast_print(tree->left,outfile,indent+4);
4482 /*------------------------------------------------------------------*/
4483 /*----------------------------*/
4485 /*----------------------------*/
4487 fprintf(outfile,"NOT (%p) type (",tree);
4488 printTypeChain(tree->ftype,outfile);
4489 fprintf(outfile,")\n");
4490 ast_print(tree->left,outfile,indent+4);
4492 /*------------------------------------------------------------------*/
4493 /*----------------------------*/
4495 /*----------------------------*/
4497 fprintf(outfile,"RRC (%p) type (",tree);
4498 printTypeChain(tree->ftype,outfile);
4499 fprintf(outfile,")\n");
4500 ast_print(tree->left,outfile,indent+4);
4504 fprintf(outfile,"RLC (%p) type (",tree);
4505 printTypeChain(tree->ftype,outfile);
4506 fprintf(outfile,")\n");
4507 ast_print(tree->left,outfile,indent+4);
4510 fprintf(outfile,"GETHBIT (%p) type (",tree);
4511 printTypeChain(tree->ftype,outfile);
4512 fprintf(outfile,")\n");
4513 ast_print(tree->left,outfile,indent+4);
4516 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4517 printTypeChain(tree->ftype,outfile);
4518 fprintf(outfile,")\n");
4519 ast_print(tree->left,outfile,indent+4);
4520 ast_print(tree->right,outfile,indent+4);
4523 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4524 printTypeChain(tree->ftype,outfile);
4525 fprintf(outfile,")\n");
4526 ast_print(tree->left,outfile,indent+4);
4527 ast_print(tree->right,outfile,indent+4);
4529 /*------------------------------------------------------------------*/
4530 /*----------------------------*/
4532 /*----------------------------*/
4533 case CAST: /* change the type */
4534 fprintf(outfile,"CAST (%p) type (",tree);
4535 printTypeChain(tree->ftype,outfile);
4536 fprintf(outfile,")\n");
4537 ast_print(tree->right,outfile,indent+4);
4541 fprintf(outfile,"ANDAND (%p) type (",tree);
4542 printTypeChain(tree->ftype,outfile);
4543 fprintf(outfile,")\n");
4544 ast_print(tree->left,outfile,indent+4);
4545 ast_print(tree->right,outfile,indent+4);
4548 fprintf(outfile,"OROR (%p) type (",tree);
4549 printTypeChain(tree->ftype,outfile);
4550 fprintf(outfile,")\n");
4551 ast_print(tree->left,outfile,indent+4);
4552 ast_print(tree->right,outfile,indent+4);
4555 /*------------------------------------------------------------------*/
4556 /*----------------------------*/
4557 /* comparison operators */
4558 /*----------------------------*/
4560 fprintf(outfile,"GT(>) (%p) type (",tree);
4561 printTypeChain(tree->ftype,outfile);
4562 fprintf(outfile,")\n");
4563 ast_print(tree->left,outfile,indent+4);
4564 ast_print(tree->right,outfile,indent+4);
4567 fprintf(outfile,"LT(<) (%p) type (",tree);
4568 printTypeChain(tree->ftype,outfile);
4569 fprintf(outfile,")\n");
4570 ast_print(tree->left,outfile,indent+4);
4571 ast_print(tree->right,outfile,indent+4);
4574 fprintf(outfile,"LE(<=) (%p) type (",tree);
4575 printTypeChain(tree->ftype,outfile);
4576 fprintf(outfile,")\n");
4577 ast_print(tree->left,outfile,indent+4);
4578 ast_print(tree->right,outfile,indent+4);
4581 fprintf(outfile,"GE(>=) (%p) type (",tree);
4582 printTypeChain(tree->ftype,outfile);
4583 fprintf(outfile,")\n");
4584 ast_print(tree->left,outfile,indent+4);
4585 ast_print(tree->right,outfile,indent+4);
4588 fprintf(outfile,"EQ(==) (%p) type (",tree);
4589 printTypeChain(tree->ftype,outfile);
4590 fprintf(outfile,")\n");
4591 ast_print(tree->left,outfile,indent+4);
4592 ast_print(tree->right,outfile,indent+4);
4595 fprintf(outfile,"NE(!=) (%p) type (",tree);
4596 printTypeChain(tree->ftype,outfile);
4597 fprintf(outfile,")\n");
4598 ast_print(tree->left,outfile,indent+4);
4599 ast_print(tree->right,outfile,indent+4);
4600 /*------------------------------------------------------------------*/
4601 /*----------------------------*/
4603 /*----------------------------*/
4604 case SIZEOF: /* evaluate wihout code generation */
4605 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4608 /*------------------------------------------------------------------*/
4609 /*----------------------------*/
4610 /* conditional operator '?' */
4611 /*----------------------------*/
4613 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4614 printTypeChain(tree->ftype,outfile);
4615 fprintf(outfile,")\n");
4616 ast_print(tree->left,outfile,indent+4);
4617 ast_print(tree->right,outfile,indent+4);
4620 fprintf(outfile,"COLON(:) (%p) type (",tree);
4621 printTypeChain(tree->ftype,outfile);
4622 fprintf(outfile,")\n");
4623 ast_print(tree->left,outfile,indent+4);
4624 ast_print(tree->right,outfile,indent+4);
4627 /*------------------------------------------------------------------*/
4628 /*----------------------------*/
4629 /* assignment operators */
4630 /*----------------------------*/
4632 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4633 printTypeChain(tree->ftype,outfile);
4634 fprintf(outfile,")\n");
4635 ast_print(tree->left,outfile,indent+4);
4636 ast_print(tree->right,outfile,indent+4);
4639 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4640 printTypeChain(tree->ftype,outfile);
4641 fprintf(outfile,")\n");
4642 ast_print(tree->left,outfile,indent+4);
4643 ast_print(tree->right,outfile,indent+4);
4646 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4647 printTypeChain(tree->ftype,outfile);
4648 fprintf(outfile,")\n");
4649 ast_print(tree->left,outfile,indent+4);
4650 ast_print(tree->right,outfile,indent+4);
4653 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4654 printTypeChain(tree->ftype,outfile);
4655 fprintf(outfile,")\n");
4656 ast_print(tree->left,outfile,indent+4);
4657 ast_print(tree->right,outfile,indent+4);
4660 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4661 printTypeChain(tree->ftype,outfile);
4662 fprintf(outfile,")\n");
4663 ast_print(tree->left,outfile,indent+4);
4664 ast_print(tree->right,outfile,indent+4);
4667 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4668 printTypeChain(tree->ftype,outfile);
4669 fprintf(outfile,")\n");
4670 ast_print(tree->left,outfile,indent+4);
4671 ast_print(tree->right,outfile,indent+4);
4674 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4675 printTypeChain(tree->ftype,outfile);
4676 fprintf(outfile,")\n");
4677 ast_print(tree->left,outfile,indent+4);
4678 ast_print(tree->right,outfile,indent+4);
4680 /*------------------------------------------------------------------*/
4681 /*----------------------------*/
4683 /*----------------------------*/
4685 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4686 printTypeChain(tree->ftype,outfile);
4687 fprintf(outfile,")\n");
4688 ast_print(tree->left,outfile,indent+4);
4689 ast_print(tree->right,outfile,indent+4);
4691 /*------------------------------------------------------------------*/
4692 /*----------------------------*/
4694 /*----------------------------*/
4696 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+4);
4700 ast_print(tree->right,outfile,indent+4);
4702 /*------------------------------------------------------------------*/
4703 /*----------------------------*/
4704 /* straight assignemnt */
4705 /*----------------------------*/
4707 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4708 printTypeChain(tree->ftype,outfile);
4709 fprintf(outfile,")\n");
4710 ast_print(tree->left,outfile,indent+4);
4711 ast_print(tree->right,outfile,indent+4);
4713 /*------------------------------------------------------------------*/
4714 /*----------------------------*/
4715 /* comma operator */
4716 /*----------------------------*/
4718 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->left,outfile,indent+4);
4722 ast_print(tree->right,outfile,indent+4);
4724 /*------------------------------------------------------------------*/
4725 /*----------------------------*/
4727 /*----------------------------*/
4730 fprintf(outfile,"CALL (%p) type (",tree);
4731 printTypeChain(tree->ftype,outfile);
4732 fprintf(outfile,")\n");
4733 ast_print(tree->left,outfile,indent+4);
4734 ast_print(tree->right,outfile,indent+4);
4737 fprintf(outfile,"PARM ");
4738 ast_print(tree->left,outfile,indent+4);
4739 if (tree->right && !IS_AST_PARAM(tree->right)) {
4740 fprintf(outfile,"PARM ");
4741 ast_print(tree->right,outfile,indent+4);
4744 /*------------------------------------------------------------------*/
4745 /*----------------------------*/
4746 /* return statement */
4747 /*----------------------------*/
4749 fprintf(outfile,"RETURN (%p) type (",tree);
4750 printTypeChain(tree->right->ftype,outfile);
4751 fprintf(outfile,")\n");
4752 ast_print(tree->right,outfile,indent+4);
4754 /*------------------------------------------------------------------*/
4755 /*----------------------------*/
4756 /* label statement */
4757 /*----------------------------*/
4759 fprintf(outfile,"LABEL (%p)",tree);
4760 ast_print(tree->left,outfile,indent+4);
4761 ast_print(tree->right,outfile,indent);
4763 /*------------------------------------------------------------------*/
4764 /*----------------------------*/
4765 /* switch statement */
4766 /*----------------------------*/
4770 fprintf(outfile,"SWITCH (%p) ",tree);
4771 ast_print(tree->left,outfile,0);
4772 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4773 INDENT(indent+4,outfile);
4774 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4775 (int) floatFromVal(val),
4776 tree->values.switchVals.swNum,
4777 (int) floatFromVal(val));
4779 ast_print(tree->right,outfile,indent);
4782 /*------------------------------------------------------------------*/
4783 /*----------------------------*/
4785 /*----------------------------*/
4787 ast_print(tree->left,outfile,indent);
4788 INDENT(indent,outfile);
4789 fprintf(outfile,"IF (%p) \n",tree);
4790 if (tree->trueLabel) {
4791 INDENT(indent,outfile);
4792 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4794 if (tree->falseLabel) {
4795 INDENT(indent,outfile);
4796 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4798 ast_print(tree->right,outfile,indent);
4800 /*------------------------------------------------------------------*/
4801 /*----------------------------*/
4803 /*----------------------------*/
4805 fprintf(outfile,"FOR (%p) \n",tree);
4806 if (AST_FOR( tree, initExpr)) {
4807 INDENT(indent+4,outfile);
4808 fprintf(outfile,"INIT EXPR ");
4809 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4811 if (AST_FOR( tree, condExpr)) {
4812 INDENT(indent+4,outfile);
4813 fprintf(outfile,"COND EXPR ");
4814 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4816 if (AST_FOR( tree, loopExpr)) {
4817 INDENT(indent+4,outfile);
4818 fprintf(outfile,"LOOP EXPR ");
4819 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4821 fprintf(outfile,"FOR LOOP BODY \n");
4822 ast_print(tree->left,outfile,indent+4);
4831 ast_print(t,stdout,1);