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))
183 /* then depending on the expression value */
184 if (floatFromVal (condAst->opval.val))
185 ifxNode = newNode (GOTO,
186 newAst_VALUE (symbolVal (trueLabel)),
189 ifxNode = newNode (GOTO,
190 newAst_VALUE (symbolVal (falseLabel)),
195 ifxNode = newNode (IFX, condAst, NULL);
196 ifxNode->trueLabel = trueLabel;
197 ifxNode->falseLabel = falseLabel;
203 /*-----------------------------------------------------------------*/
204 /* copyAstValues - copies value portion of ast if needed */
205 /*-----------------------------------------------------------------*/
207 copyAstValues (ast * dest, ast * src)
209 switch (src->opval.op)
212 dest->values.sym = copySymbolChain (src->values.sym);
216 dest->values.switchVals.swVals =
217 copyValue (src->values.switchVals.swVals);
218 dest->values.switchVals.swDefault =
219 src->values.switchVals.swDefault;
220 dest->values.switchVals.swNum =
221 src->values.switchVals.swNum;
225 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
226 strcpy (dest->values.inlineasm, src->values.inlineasm);
230 dest->values.constlist = copyLiteralList(src->values.constlist);
234 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
235 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
236 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
237 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
238 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
239 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
240 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
245 /*-----------------------------------------------------------------*/
246 /* copyAst - makes a copy of a given astession */
247 /*-----------------------------------------------------------------*/
256 dest = Safe_calloc (1, sizeof (ast));
258 dest->type = src->type;
259 dest->lineno = src->lineno;
260 dest->level = src->level;
261 dest->funcName = src->funcName;
262 dest->argSym = src->argSym;
264 /* if this is a leaf */
266 if (src->type == EX_VALUE)
268 dest->opval.val = copyValue (src->opval.val);
273 if (src->type == EX_LINK)
275 dest->opval.lnk = copyLinkChain (src->opval.lnk);
279 dest->opval.op = src->opval.op;
281 /* if this is a node that has special values */
282 copyAstValues (dest, src);
285 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
287 dest->trueLabel = copySymbol (src->trueLabel);
288 dest->falseLabel = copySymbol (src->falseLabel);
289 dest->left = copyAst (src->left);
290 dest->right = copyAst (src->right);
296 /*-----------------------------------------------------------------*/
297 /* hasSEFcalls - returns TRUE if tree has a function call */
298 /*-----------------------------------------------------------------*/
300 hasSEFcalls (ast * tree)
305 if (tree->type == EX_OP &&
306 (tree->opval.op == CALL ||
307 tree->opval.op == PCALL ||
308 tree->opval.op == '=' ||
309 tree->opval.op == INC_OP ||
310 tree->opval.op == DEC_OP))
313 return (hasSEFcalls (tree->left) |
314 hasSEFcalls (tree->right));
317 /*-----------------------------------------------------------------*/
318 /* isAstEqual - compares two asts & returns 1 if they are equal */
319 /*-----------------------------------------------------------------*/
321 isAstEqual (ast * t1, ast * t2)
330 if (t1->type != t2->type)
336 if (t1->opval.op != t2->opval.op)
338 return (isAstEqual (t1->left, t2->left) &&
339 isAstEqual (t1->right, t2->right));
343 if (t1->opval.val->sym)
345 if (!t2->opval.val->sym)
348 return isSymbolEqual (t1->opval.val->sym,
353 if (t2->opval.val->sym)
356 return (floatFromVal (t1->opval.val) ==
357 floatFromVal (t2->opval.val));
361 /* only compare these two types */
369 /*-----------------------------------------------------------------*/
370 /* resolveSymbols - resolve symbols from the symbol table */
371 /*-----------------------------------------------------------------*/
373 resolveSymbols (ast * tree)
375 /* walk the entire tree and check for values */
376 /* with symbols if we find one then replace */
377 /* symbol with that from the symbol table */
383 /* if not block & function */
384 if (tree->type == EX_OP &&
385 (tree->opval.op != FUNCTION &&
386 tree->opval.op != BLOCK &&
387 tree->opval.op != NULLOP))
389 filename = tree->filename;
390 lineno = tree->lineno;
393 /* make sure we resolve the true & false labels for ifx */
394 if (tree->type == EX_OP && tree->opval.op == IFX)
400 if ((csym = findSym (LabelTab, tree->trueLabel,
401 tree->trueLabel->name)))
402 tree->trueLabel = csym;
404 werror (E_LABEL_UNDEF, tree->trueLabel->name);
407 if (tree->falseLabel)
409 if ((csym = findSym (LabelTab,
411 tree->falseLabel->name)))
412 tree->falseLabel = csym;
414 werror (E_LABEL_UNDEF, tree->falseLabel->name);
419 /* if this is a label resolve it from the labelTab */
420 if (IS_AST_VALUE (tree) &&
421 tree->opval.val->sym &&
422 tree->opval.val->sym->islbl)
425 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
426 tree->opval.val->sym->name);
429 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
431 tree->opval.val->sym = csym;
433 goto resolveChildren;
436 /* do only for leafs */
437 if (IS_AST_VALUE (tree) &&
438 tree->opval.val->sym &&
439 !tree->opval.val->sym->implicit)
442 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
444 /* if found in the symbol table & they r not the same */
445 if (csym && tree->opval.val->sym != csym)
447 tree->opval.val->sym = csym;
448 tree->opval.val->type = csym->type;
449 tree->opval.val->etype = csym->etype;
452 /* if not found in the symbol table */
453 /* mark it as undefined assume it is */
454 /* an integer in data space */
455 if (!csym && !tree->opval.val->sym->implicit)
458 /* if this is a function name then */
459 /* mark it as returning an int */
462 tree->opval.val->sym->type = newLink ();
463 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
464 tree->opval.val->sym->type->next =
465 tree->opval.val->sym->etype = newIntLink ();
466 tree->opval.val->etype = tree->opval.val->etype;
467 tree->opval.val->type = tree->opval.val->sym->type;
468 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
469 allocVariables (tree->opval.val->sym);
473 tree->opval.val->sym->undefined = 1;
474 tree->opval.val->type =
475 tree->opval.val->etype = newIntLink ();
476 tree->opval.val->sym->type =
477 tree->opval.val->sym->etype = newIntLink ();
483 resolveSymbols (tree->left);
484 resolveSymbols (tree->right);
489 /*-----------------------------------------------------------------*/
490 /* setAstLineno - walks a ast tree & sets the line number */
491 /*-----------------------------------------------------------------*/
493 setAstLineno (ast * tree, int lineno)
498 tree->lineno = lineno;
499 setAstLineno (tree->left, lineno);
500 setAstLineno (tree->right, lineno);
505 /* this functions seems to be superfluous?! kmh */
507 /*-----------------------------------------------------------------*/
508 /* resolveFromTable - will return the symbal table value */
509 /*-----------------------------------------------------------------*/
511 resolveFromTable (value * val)
518 csym = findSymWithLevel (SymbolTab, val->sym);
520 /* if found in the symbol table & they r not the same */
521 if (csym && val->sym != csym &&
522 csym->level == val->sym->level &&
528 val->type = csym->type;
529 val->etype = csym->etype;
536 /*-----------------------------------------------------------------*/
537 /* funcOfType :- function of type with name */
538 /*-----------------------------------------------------------------*/
540 funcOfType (char *name, sym_link * type, sym_link * argType,
544 /* create the symbol */
545 sym = newSymbol (name, 0);
547 /* if arguments required */
552 args = sym->args = newValue ();
556 args->type = copyLinkChain (argType);
557 args->etype = getSpec (args->type);
560 args = args->next = newValue ();
564 /* setup return value */
565 sym->type = newLink ();
566 DCL_TYPE (sym->type) = FUNCTION;
567 sym->type->next = copyLinkChain (type);
568 sym->etype = getSpec (sym->type);
569 SPEC_RENT (sym->etype) = rent;
574 allocVariables (sym);
579 /*-----------------------------------------------------------------*/
580 /* reverseParms - will reverse a parameter tree */
581 /*-----------------------------------------------------------------*/
583 reverseParms (ast * ptree)
589 /* top down if we find a nonParm tree then quit */
590 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
593 ptree->left = ptree->right;
594 ptree->right = ttree;
595 reverseParms (ptree->left);
596 reverseParms (ptree->right);
602 /*-----------------------------------------------------------------*/
603 /* processParms - makes sure the parameters are okay and do some */
604 /* processing with them */
605 /*-----------------------------------------------------------------*/
607 processParms (ast * func,
613 sym_link *fetype = func->etype;
615 /* if none of them exist */
616 if (!defParm && !actParm)
620 if (getenv("DEBUG_SANITY")) {
621 fprintf (stderr, "addSym: %s ", defParm->name);
623 /* make sure the type is complete and sane */
624 checkTypeSanity(defParm->etype, defParm->name);
627 /* if the function is being called via a pointer & */
628 /* it has not been defined a reentrant then we cannot */
629 /* have parameters */
630 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
632 werror (E_NONRENT_ARGS);
636 /* if defined parameters ended but actual parameters */
637 /* exist and this is not defined as a variable arg */
638 /* also check if statckAuto option is specified */
639 if ((!defParm) && actParm && (!func->hasVargs) &&
640 !options.stackAuto && !IS_RENT (fetype))
642 werror (E_TOO_MANY_PARMS);
646 /* if defined parameters present but no actual parameters */
647 if (defParm && !actParm)
649 werror (E_TOO_FEW_PARMS);
653 /* If this is a varargs function... */
654 if (!defParm && actParm && func->hasVargs)
659 if (IS_CAST_OP (actParm)
660 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
662 /* Parameter was explicitly typecast; don't touch it. */
666 /* The ternary ('?') operator is weird: the ftype of the
667 * operator is the type of the condition, but it will return a
668 * (possibly) different type.
670 if (IS_TERNARY_OP(actParm))
672 assert(IS_COLON_OP(actParm->right));
673 assert(actParm->right->left);
674 ftype = actParm->right->left->ftype;
678 ftype = actParm->ftype;
681 /* If it's a small integer, upcast to int. */
682 if (IS_INTEGRAL (ftype)
683 && (getSize (ftype) < (unsigned) INTSIZE))
685 newType = newAst_LINK(INTTYPE);
688 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
690 newType = newAst_LINK (copyLinkChain(ftype));
691 DCL_TYPE (newType->opval.lnk) = GPOINTER;
694 if (IS_AGGREGATE (ftype))
696 newType = newAst_LINK (copyLinkChain (ftype));
697 DCL_TYPE (newType->opval.lnk) = GPOINTER;
701 /* cast required; change this op to a cast. */
702 ast *parmCopy = resolveSymbols (copyAst (actParm));
704 actParm->type = EX_OP;
705 actParm->opval.op = CAST;
706 actParm->left = newType;
707 actParm->right = parmCopy;
708 decorateType (actParm);
710 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
712 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
713 processParms (func, NULL, actParm->right, parmNumber, rightmost));
718 /* if defined parameters ended but actual has not & */
720 if (!defParm && actParm &&
721 (options.stackAuto || IS_RENT (fetype)))
724 resolveSymbols (actParm);
725 /* if this is a PARAM node then match left & right */
726 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
728 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
729 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
733 /* If we have found a value node by following only right-hand links,
734 * then we know that there are no more values after us.
736 * Therefore, if there are more defined parameters, the caller didn't
739 if (rightmost && defParm->next)
741 werror (E_TOO_FEW_PARMS);
746 /* the parameter type must be at least castable */
747 if (compareType (defParm->type, actParm->ftype) == 0)
749 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
750 werror (E_CONTINUE, "defined type ");
751 printTypeChain (defParm->type, stderr);
752 fprintf (stderr, "\n");
753 werror (E_CONTINUE, "actual type ");
754 printTypeChain (actParm->ftype, stderr);
755 fprintf (stderr, "\n");
758 /* if the parameter is castable then add the cast */
759 if (compareType (defParm->type, actParm->ftype) < 0)
761 ast *pTree = resolveSymbols (copyAst (actParm));
763 /* now change the current one to a cast */
764 actParm->type = EX_OP;
765 actParm->opval.op = CAST;
766 actParm->left = newAst_LINK (defParm->type);
767 actParm->right = pTree;
768 actParm->etype = defParm->etype;
769 actParm->ftype = defParm->type;
772 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
774 actParm->argSym = defParm->sym;
775 /* make a copy and change the regparm type to the defined parm */
776 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
777 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
781 /*-----------------------------------------------------------------*/
782 /* createIvalType - generates ival for basic types */
783 /*-----------------------------------------------------------------*/
785 createIvalType (ast * sym, sym_link * type, initList * ilist)
789 /* if initList is deep */
790 if (ilist->type == INIT_DEEP)
791 ilist = ilist->init.deep;
793 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
794 return decorateType (newNode ('=', sym, iExpr));
797 /*-----------------------------------------------------------------*/
798 /* createIvalStruct - generates initial value for structures */
799 /*-----------------------------------------------------------------*/
801 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
807 sflds = SPEC_STRUCT (type)->fields;
808 if (ilist->type != INIT_DEEP)
810 werror (E_INIT_STRUCT, "");
814 iloop = ilist->init.deep;
816 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
820 /* if we have come to end */
824 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
825 lAst = decorateType (resolveSymbols (lAst));
826 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
832 /*-----------------------------------------------------------------*/
833 /* createIvalArray - generates code for array initialization */
834 /*-----------------------------------------------------------------*/
836 createIvalArray (ast * sym, sym_link * type, initList * ilist)
840 int lcnt = 0, size = 0;
841 literalList *literalL;
843 /* take care of the special case */
844 /* array of characters can be init */
846 if (IS_CHAR (type->next))
847 if ((rast = createIvalCharPtr (sym,
849 decorateType (resolveSymbols (list2expr (ilist))))))
851 return decorateType (resolveSymbols (rast));
853 /* not the special case */
854 if (ilist->type != INIT_DEEP)
856 werror (E_INIT_STRUCT, "");
860 iloop = ilist->init.deep;
861 lcnt = DCL_ELEM (type);
863 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
867 aSym = decorateType (resolveSymbols(sym));
869 rast = newNode(ARRAYINIT, aSym, NULL);
870 rast->values.constlist = literalL;
872 // Make sure size is set to length of initializer list.
879 if (lcnt && size > lcnt)
881 // Array size was specified, and we have more initializers than needed.
882 char *name=sym->opval.val->sym->name;
883 int lineno=sym->opval.val->sym->lineDef;
885 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
894 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
895 aSym = decorateType (resolveSymbols (aSym));
896 rast = createIval (aSym, type->next, iloop, rast);
897 iloop = (iloop ? iloop->next : NULL);
903 /* no of elements given and we */
904 /* have generated for all of them */
907 // there has to be a better way
908 char *name=sym->opval.val->sym->name;
909 int lineno=sym->opval.val->sym->lineDef;
910 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
917 /* if we have not been given a size */
918 if (!DCL_ELEM (type))
920 DCL_ELEM (type) = size;
923 return decorateType (resolveSymbols (rast));
927 /*-----------------------------------------------------------------*/
928 /* createIvalCharPtr - generates initial values for char pointers */
929 /*-----------------------------------------------------------------*/
931 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
935 /* if this is a pointer & right is a literal array then */
936 /* just assignment will do */
937 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
938 SPEC_SCLS (iexpr->etype) == S_CODE)
939 && IS_ARRAY (iexpr->ftype)))
940 return newNode ('=', sym, iexpr);
942 /* left side is an array so we have to assign each */
944 if ((IS_LITERAL (iexpr->etype) ||
945 SPEC_SCLS (iexpr->etype) == S_CODE)
946 && IS_ARRAY (iexpr->ftype))
948 /* for each character generate an assignment */
949 /* to the array element */
950 char *s = SPEC_CVAL (iexpr->etype).v_char;
955 rast = newNode (NULLOP,
959 newAst_VALUE (valueFromLit ((float) i))),
960 newAst_VALUE (valueFromLit (*s))));
964 rast = newNode (NULLOP,
968 newAst_VALUE (valueFromLit ((float) i))),
969 newAst_VALUE (valueFromLit (*s))));
970 return decorateType (resolveSymbols (rast));
976 /*-----------------------------------------------------------------*/
977 /* createIvalPtr - generates initial value for pointers */
978 /*-----------------------------------------------------------------*/
980 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
986 if (ilist->type == INIT_DEEP)
987 ilist = ilist->init.deep;
989 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
991 /* if character pointer */
992 if (IS_CHAR (type->next))
993 if ((rast = createIvalCharPtr (sym, type, iexpr)))
996 return newNode ('=', sym, iexpr);
999 /*-----------------------------------------------------------------*/
1000 /* createIval - generates code for initial value */
1001 /*-----------------------------------------------------------------*/
1003 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1010 /* if structure then */
1011 if (IS_STRUCT (type))
1012 rast = createIvalStruct (sym, type, ilist);
1014 /* if this is a pointer */
1016 rast = createIvalPtr (sym, type, ilist);
1018 /* if this is an array */
1019 if (IS_ARRAY (type))
1020 rast = createIvalArray (sym, type, ilist);
1022 /* if type is SPECIFIER */
1024 rast = createIvalType (sym, type, ilist);
1026 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1028 return decorateType (resolveSymbols (rast));
1031 /*-----------------------------------------------------------------*/
1032 /* initAggregates - initialises aggregate variables with initv */
1033 /*-----------------------------------------------------------------*/
1035 initAggregates (symbol * sym, initList * ival, ast * wid)
1037 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1040 /*-----------------------------------------------------------------*/
1041 /* gatherAutoInit - creates assignment expressions for initial */
1043 /*-----------------------------------------------------------------*/
1045 gatherAutoInit (symbol * autoChain)
1052 for (sym = autoChain; sym; sym = sym->next)
1055 /* resolve the symbols in the ival */
1057 resolveIvalSym (sym->ival);
1059 /* if this is a static variable & has an */
1060 /* initial value the code needs to be lifted */
1061 /* here to the main portion since they can be */
1062 /* initialised only once at the start */
1063 if (IS_STATIC (sym->etype) && sym->ival &&
1064 SPEC_SCLS (sym->etype) != S_CODE)
1068 // this can only be a constant
1069 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1070 werror (E_CONST_EXPECTED);
1073 /* insert the symbol into the symbol table */
1074 /* with level = 0 & name = rname */
1075 newSym = copySymbol (sym);
1076 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1078 /* now lift the code to main */
1079 if (IS_AGGREGATE (sym->type))
1080 work = initAggregates (sym, sym->ival, NULL);
1082 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1083 list2expr (sym->ival));
1085 setAstLineno (work, sym->lineDef);
1089 staticAutos = newNode (NULLOP, staticAutos, work);
1096 /* if there is an initial value */
1097 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1099 if (IS_AGGREGATE (sym->type))
1100 work = initAggregates (sym, sym->ival, NULL);
1102 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1103 list2expr (sym->ival));
1105 setAstLineno (work, sym->lineDef);
1108 init = newNode (NULLOP, init, work);
1117 /*-----------------------------------------------------------------*/
1118 /* stringToSymbol - creates a symbol from a literal string */
1119 /*-----------------------------------------------------------------*/
1121 stringToSymbol (value * val)
1123 char name[SDCC_NAME_MAX + 1];
1124 static int charLbl = 0;
1127 sprintf (name, "_str_%d", charLbl++);
1128 sym = newSymbol (name, 0); /* make it @ level 0 */
1129 strcpy (sym->rname, name);
1131 /* copy the type from the value passed */
1132 sym->type = copyLinkChain (val->type);
1133 sym->etype = getSpec (sym->type);
1134 /* change to storage class & output class */
1135 SPEC_SCLS (sym->etype) = S_CODE;
1136 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1137 SPEC_STAT (sym->etype) = 1;
1138 /* make the level & block = 0 */
1139 sym->block = sym->level = 0;
1141 /* create an ival */
1142 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1147 allocVariables (sym);
1150 return symbolVal (sym);
1154 /*-----------------------------------------------------------------*/
1155 /* processBlockVars - will go thru the ast looking for block if */
1156 /* a block is found then will allocate the syms */
1157 /* will also gather the auto inits present */
1158 /*-----------------------------------------------------------------*/
1160 processBlockVars (ast * tree, int *stack, int action)
1165 /* if this is a block */
1166 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1170 if (action == ALLOCATE)
1172 autoInit = gatherAutoInit (tree->values.sym);
1173 *stack += allocVariables (tree->values.sym);
1175 /* if there are auto inits then do them */
1177 tree->left = newNode (NULLOP, autoInit, tree->left);
1179 else /* action is deallocate */
1180 deallocLocal (tree->values.sym);
1183 processBlockVars (tree->left, stack, action);
1184 processBlockVars (tree->right, stack, action);
1188 /*-----------------------------------------------------------------*/
1189 /* constExprValue - returns the value of a constant expression */
1190 /*-----------------------------------------------------------------*/
1192 constExprValue (ast * cexpr, int check)
1194 cexpr = decorateType (resolveSymbols (cexpr));
1196 /* if this is not a constant then */
1197 if (!IS_LITERAL (cexpr->ftype))
1199 /* then check if this is a literal array
1201 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1202 SPEC_CVAL (cexpr->etype).v_char &&
1203 IS_ARRAY (cexpr->ftype))
1205 value *val = valFromType (cexpr->ftype);
1206 SPEC_SCLS (val->etype) = S_LITERAL;
1207 val->sym = cexpr->opval.val->sym;
1208 val->sym->type = copyLinkChain (cexpr->ftype);
1209 val->sym->etype = getSpec (val->sym->type);
1210 strcpy (val->name, cexpr->opval.val->sym->rname);
1214 /* if we are casting a literal value then */
1215 if (IS_AST_OP (cexpr) &&
1216 cexpr->opval.op == CAST &&
1217 IS_LITERAL (cexpr->left->ftype))
1218 return valCastLiteral (cexpr->ftype,
1219 floatFromVal (cexpr->left->opval.val));
1221 if (IS_AST_VALUE (cexpr))
1222 return cexpr->opval.val;
1225 werror (E_CONST_EXPECTED, "found expression");
1230 /* return the value */
1231 return cexpr->opval.val;
1235 /*-----------------------------------------------------------------*/
1236 /* isLabelInAst - will return true if a given label is found */
1237 /*-----------------------------------------------------------------*/
1239 isLabelInAst (symbol * label, ast * tree)
1241 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1244 if (IS_AST_OP (tree) &&
1245 tree->opval.op == LABEL &&
1246 isSymbolEqual (AST_SYMBOL (tree->left), label))
1249 return isLabelInAst (label, tree->right) &&
1250 isLabelInAst (label, tree->left);
1254 /*-----------------------------------------------------------------*/
1255 /* isLoopCountable - return true if the loop count can be determi- */
1256 /* -ned at compile time . */
1257 /*-----------------------------------------------------------------*/
1259 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1260 symbol ** sym, ast ** init, ast ** end)
1263 /* the loop is considered countable if the following
1264 conditions are true :-
1266 a) initExpr :- <sym> = <const>
1267 b) condExpr :- <sym> < <const1>
1268 c) loopExpr :- <sym> ++
1271 /* first check the initExpr */
1272 if (IS_AST_OP (initExpr) &&
1273 initExpr->opval.op == '=' && /* is assignment */
1274 IS_AST_SYM_VALUE (initExpr->left))
1275 { /* left is a symbol */
1277 *sym = AST_SYMBOL (initExpr->left);
1278 *init = initExpr->right;
1283 /* for now the symbol has to be of
1285 if (!IS_INTEGRAL ((*sym)->type))
1288 /* now check condExpr */
1289 if (IS_AST_OP (condExpr))
1292 switch (condExpr->opval.op)
1295 if (IS_AST_SYM_VALUE (condExpr->left) &&
1296 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1297 IS_AST_LIT_VALUE (condExpr->right))
1299 *end = condExpr->right;
1305 if (IS_AST_OP (condExpr->left) &&
1306 condExpr->left->opval.op == '>' &&
1307 IS_AST_LIT_VALUE (condExpr->left->right) &&
1308 IS_AST_SYM_VALUE (condExpr->left->left) &&
1309 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1312 *end = newNode ('+', condExpr->left->right,
1313 newAst_VALUE (constVal ("1")));
1324 /* check loop expression is of the form <sym>++ */
1325 if (!IS_AST_OP (loopExpr))
1328 /* check if <sym> ++ */
1329 if (loopExpr->opval.op == INC_OP)
1335 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1336 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1343 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1344 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1352 if (loopExpr->opval.op == ADD_ASSIGN)
1355 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1356 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1357 IS_AST_LIT_VALUE (loopExpr->right) &&
1358 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1366 /*-----------------------------------------------------------------*/
1367 /* astHasVolatile - returns true if ast contains any volatile */
1368 /*-----------------------------------------------------------------*/
1370 astHasVolatile (ast * tree)
1375 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1378 if (IS_AST_OP (tree))
1379 return astHasVolatile (tree->left) ||
1380 astHasVolatile (tree->right);
1385 /*-----------------------------------------------------------------*/
1386 /* astHasPointer - return true if the ast contains any ptr variable */
1387 /*-----------------------------------------------------------------*/
1389 astHasPointer (ast * tree)
1394 if (IS_AST_LINK (tree))
1397 /* if we hit an array expression then check
1398 only the left side */
1399 if (IS_AST_OP (tree) && tree->opval.op == '[')
1400 return astHasPointer (tree->left);
1402 if (IS_AST_VALUE (tree))
1403 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1405 return astHasPointer (tree->left) ||
1406 astHasPointer (tree->right);
1410 /*-----------------------------------------------------------------*/
1411 /* astHasSymbol - return true if the ast has the given symbol */
1412 /*-----------------------------------------------------------------*/
1414 astHasSymbol (ast * tree, symbol * sym)
1416 if (!tree || IS_AST_LINK (tree))
1419 if (IS_AST_VALUE (tree))
1421 if (IS_AST_SYM_VALUE (tree))
1422 return isSymbolEqual (AST_SYMBOL (tree), sym);
1427 return astHasSymbol (tree->left, sym) ||
1428 astHasSymbol (tree->right, sym);
1431 /*-----------------------------------------------------------------*/
1432 /* astHasDeref - return true if the ast has an indirect access */
1433 /*-----------------------------------------------------------------*/
1435 astHasDeref (ast * tree)
1437 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1440 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1442 return astHasDeref (tree->left) || astHasDeref (tree->right);
1445 /*-----------------------------------------------------------------*/
1446 /* isConformingBody - the loop body has to conform to a set of rules */
1447 /* for the loop to be considered reversible read on for rules */
1448 /*-----------------------------------------------------------------*/
1450 isConformingBody (ast * pbody, symbol * sym, ast * body)
1453 /* we are going to do a pre-order traversal of the
1454 tree && check for the following conditions. (essentially
1455 a set of very shallow tests )
1456 a) the sym passed does not participate in
1457 any arithmetic operation
1458 b) There are no function calls
1459 c) all jumps are within the body
1460 d) address of loop control variable not taken
1461 e) if an assignment has a pointer on the
1462 left hand side make sure right does not have
1463 loop control variable */
1465 /* if we reach the end or a leaf then true */
1466 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1470 /* if anything else is "volatile" */
1471 if (IS_VOLATILE (TETYPE (pbody)))
1474 /* we will walk the body in a pre-order traversal for
1476 switch (pbody->opval.op)
1478 /*------------------------------------------------------------------*/
1480 return isConformingBody (pbody->right, sym, body);
1482 /*------------------------------------------------------------------*/
1487 /*------------------------------------------------------------------*/
1488 case INC_OP: /* incerement operator unary so left only */
1491 /* sure we are not sym is not modified */
1493 IS_AST_SYM_VALUE (pbody->left) &&
1494 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1498 IS_AST_SYM_VALUE (pbody->right) &&
1499 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1504 /*------------------------------------------------------------------*/
1506 case '*': /* can be unary : if right is null then unary operation */
1511 /* if right is NULL then unary operation */
1512 /*------------------------------------------------------------------*/
1513 /*----------------------------*/
1515 /*----------------------------*/
1518 if (IS_AST_SYM_VALUE (pbody->left) &&
1519 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1522 return isConformingBody (pbody->left, sym, body);
1526 if (astHasSymbol (pbody->left, sym) ||
1527 astHasSymbol (pbody->right, sym))
1532 /*------------------------------------------------------------------*/
1540 if (IS_AST_SYM_VALUE (pbody->left) &&
1541 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1544 if (IS_AST_SYM_VALUE (pbody->right) &&
1545 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1548 return isConformingBody (pbody->left, sym, body) &&
1549 isConformingBody (pbody->right, sym, body);
1556 if (IS_AST_SYM_VALUE (pbody->left) &&
1557 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1559 return isConformingBody (pbody->left, sym, body);
1561 /*------------------------------------------------------------------*/
1573 case SIZEOF: /* evaluate wihout code generation */
1575 return isConformingBody (pbody->left, sym, body) &&
1576 isConformingBody (pbody->right, sym, body);
1578 /*------------------------------------------------------------------*/
1581 /* if left has a pointer & right has loop
1582 control variable then we cannot */
1583 if (astHasPointer (pbody->left) &&
1584 astHasSymbol (pbody->right, sym))
1586 if (astHasVolatile (pbody->left))
1589 if (IS_AST_SYM_VALUE (pbody->left) &&
1590 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1593 if (astHasVolatile (pbody->left))
1596 if (astHasDeref(pbody->right)) return FALSE;
1598 return isConformingBody (pbody->left, sym, body) &&
1599 isConformingBody (pbody->right, sym, body);
1610 assert ("Parser should not have generated this\n");
1612 /*------------------------------------------------------------------*/
1613 /*----------------------------*/
1614 /* comma operator */
1615 /*----------------------------*/
1617 return isConformingBody (pbody->left, sym, body) &&
1618 isConformingBody (pbody->right, sym, body);
1620 /*------------------------------------------------------------------*/
1621 /*----------------------------*/
1623 /*----------------------------*/
1627 /*------------------------------------------------------------------*/
1628 /*----------------------------*/
1629 /* return statement */
1630 /*----------------------------*/
1635 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1640 if (astHasSymbol (pbody->left, sym))
1647 return isConformingBody (pbody->left, sym, body) &&
1648 isConformingBody (pbody->right, sym, body);
1654 /*-----------------------------------------------------------------*/
1655 /* isLoopReversible - takes a for loop as input && returns true */
1656 /* if the for loop is reversible. If yes will set the value of */
1657 /* the loop control var & init value & termination value */
1658 /*-----------------------------------------------------------------*/
1660 isLoopReversible (ast * loop, symbol ** loopCntrl,
1661 ast ** init, ast ** end)
1663 /* if option says don't do it then don't */
1664 if (optimize.noLoopReverse)
1666 /* there are several tests to determine this */
1668 /* for loop has to be of the form
1669 for ( <sym> = <const1> ;
1670 [<sym> < <const2>] ;
1671 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1673 if (!isLoopCountable (AST_FOR (loop, initExpr),
1674 AST_FOR (loop, condExpr),
1675 AST_FOR (loop, loopExpr),
1676 loopCntrl, init, end))
1679 /* now do some serious checking on the body of the loop
1682 return isConformingBody (loop->left, *loopCntrl, loop->left);
1686 /*-----------------------------------------------------------------*/
1687 /* replLoopSym - replace the loop sym by loop sym -1 */
1688 /*-----------------------------------------------------------------*/
1690 replLoopSym (ast * body, symbol * sym)
1693 if (!body || IS_AST_LINK (body))
1696 if (IS_AST_SYM_VALUE (body))
1699 if (isSymbolEqual (AST_SYMBOL (body), sym))
1703 body->opval.op = '-';
1704 body->left = newAst_VALUE (symbolVal (sym));
1705 body->right = newAst_VALUE (constVal ("1"));
1713 replLoopSym (body->left, sym);
1714 replLoopSym (body->right, sym);
1718 /*-----------------------------------------------------------------*/
1719 /* reverseLoop - do the actual loop reversal */
1720 /*-----------------------------------------------------------------*/
1722 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1726 /* create the following tree
1731 if (sym) goto for_continue ;
1734 /* put it together piece by piece */
1735 rloop = newNode (NULLOP,
1736 createIf (newAst_VALUE (symbolVal (sym)),
1738 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1741 newAst_VALUE (symbolVal (sym)),
1744 replLoopSym (loop->left, sym);
1746 rloop = newNode (NULLOP,
1748 newAst_VALUE (symbolVal (sym)),
1749 newNode ('-', end, init)),
1750 createLabel (AST_FOR (loop, continueLabel),
1754 newNode (SUB_ASSIGN,
1755 newAst_VALUE (symbolVal (sym)),
1756 newAst_VALUE (constVal ("1"))),
1759 return decorateType (rloop);
1763 //#define DEMAND_INTEGER_PROMOTION
1765 #ifdef DEMAND_INTEGER_PROMOTION
1767 /*-----------------------------------------------------------------*/
1768 /* walk a tree looking for the leaves. Add a typecast to the given */
1769 /* type to each value leaf node. */
1770 /*-----------------------------------------------------------------*/
1772 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1774 if (!node || IS_CALLOP(node))
1776 /* WTF? We should never get here. */
1780 if (!node->left && !node->right)
1782 /* We're at a leaf; if it's a value, apply the typecast */
1783 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1785 *parentPtr = decorateType (newNode (CAST,
1786 newAst_LINK (copyLinkChain (type)),
1794 pushTypeCastToLeaves (type, node->left, &(node->left));
1798 pushTypeCastToLeaves (type, node->right, &(node->right));
1805 /*-----------------------------------------------------------------*/
1806 /* Given an assignment operation in a tree, determine if the LHS */
1807 /* (the result) has a different (integer) type than the RHS. */
1808 /* If so, walk the RHS and add a typecast to the type of the LHS */
1809 /* to all leaf nodes. */
1810 /*-----------------------------------------------------------------*/
1812 propAsgType (ast * tree)
1814 #ifdef DEMAND_INTEGER_PROMOTION
1815 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1817 /* Nothing to do here... */
1821 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1823 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1830 /*-----------------------------------------------------------------*/
1831 /* decorateType - compute type for this tree also does type cheking */
1832 /* this is done bottom up, since type have to flow upwards */
1833 /* it also does constant folding, and paramater checking */
1834 /*-----------------------------------------------------------------*/
1836 decorateType (ast * tree)
1844 /* if already has type then do nothing */
1845 if (tree->decorated)
1848 tree->decorated = 1;
1850 /* print the line */
1851 /* if not block & function */
1852 if (tree->type == EX_OP &&
1853 (tree->opval.op != FUNCTION &&
1854 tree->opval.op != BLOCK &&
1855 tree->opval.op != NULLOP))
1857 filename = tree->filename;
1858 lineno = tree->lineno;
1861 /* if any child is an error | this one is an error do nothing */
1862 if (tree->isError ||
1863 (tree->left && tree->left->isError) ||
1864 (tree->right && tree->right->isError))
1867 /*------------------------------------------------------------------*/
1868 /*----------------------------*/
1869 /* leaf has been reached */
1870 /*----------------------------*/
1871 /* if this is of type value */
1872 /* just get the type */
1873 if (tree->type == EX_VALUE)
1876 if (IS_LITERAL (tree->opval.val->etype))
1879 /* if this is a character array then declare it */
1880 if (IS_ARRAY (tree->opval.val->type))
1881 tree->opval.val = stringToSymbol (tree->opval.val);
1883 /* otherwise just copy the type information */
1884 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1885 if (funcInChain (tree->opval.val->type))
1887 tree->hasVargs = tree->opval.val->sym->hasVargs;
1888 tree->args = copyValueChain (tree->opval.val->sym->args);
1893 if (tree->opval.val->sym)
1895 /* if the undefined flag is set then give error message */
1896 if (tree->opval.val->sym->undefined)
1898 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1900 TTYPE (tree) = TETYPE (tree) =
1901 tree->opval.val->type = tree->opval.val->sym->type =
1902 tree->opval.val->etype = tree->opval.val->sym->etype =
1903 copyLinkChain (INTTYPE);
1908 /* if impilicit i.e. struct/union member then no type */
1909 if (tree->opval.val->sym->implicit)
1910 TTYPE (tree) = TETYPE (tree) = NULL;
1915 /* else copy the type */
1916 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1918 /* and mark it as referenced */
1919 tree->opval.val->sym->isref = 1;
1920 /* if this is of type function or function pointer */
1921 if (funcInChain (tree->opval.val->type))
1923 tree->hasVargs = tree->opval.val->sym->hasVargs;
1924 tree->args = copyValueChain (tree->opval.val->sym->args);
1934 /* if type link for the case of cast */
1935 if (tree->type == EX_LINK)
1937 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1944 dtl = decorateType (tree->left);
1945 dtr = decorateType (tree->right);
1947 /* this is to take care of situations
1948 when the tree gets rewritten */
1949 if (dtl != tree->left)
1951 if (dtr != tree->right)
1955 /* depending on type of operator do */
1957 switch (tree->opval.op)
1959 /*------------------------------------------------------------------*/
1960 /*----------------------------*/
1962 /*----------------------------*/
1965 /* determine which is the array & which the index */
1966 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1969 ast *tempTree = tree->left;
1970 tree->left = tree->right;
1971 tree->right = tempTree;
1974 /* first check if this is a array or a pointer */
1975 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1977 werror (E_NEED_ARRAY_PTR, "[]");
1978 goto errorTreeReturn;
1981 /* check if the type of the idx */
1982 if (!IS_INTEGRAL (RTYPE (tree)))
1984 werror (E_IDX_NOT_INT);
1985 goto errorTreeReturn;
1988 /* if the left is an rvalue then error */
1991 werror (E_LVALUE_REQUIRED, "array access");
1992 goto errorTreeReturn;
1995 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1996 if (IS_PTR(LTYPE(tree))) {
1997 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2001 /*------------------------------------------------------------------*/
2002 /*----------------------------*/
2004 /*----------------------------*/
2006 /* if this is not a structure */
2007 if (!IS_STRUCT (LTYPE (tree)))
2009 werror (E_STRUCT_UNION, ".");
2010 goto errorTreeReturn;
2012 TTYPE (tree) = structElemType (LTYPE (tree),
2013 (tree->right->type == EX_VALUE ?
2014 tree->right->opval.val : NULL), &tree->args);
2015 TETYPE (tree) = getSpec (TTYPE (tree));
2018 /*------------------------------------------------------------------*/
2019 /*----------------------------*/
2020 /* struct/union pointer */
2021 /*----------------------------*/
2023 /* if not pointer to a structure */
2024 if (!IS_PTR (LTYPE (tree)))
2026 werror (E_PTR_REQD);
2027 goto errorTreeReturn;
2030 if (!IS_STRUCT (LTYPE (tree)->next))
2032 werror (E_STRUCT_UNION, "->");
2033 goto errorTreeReturn;
2036 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2037 (tree->right->type == EX_VALUE ?
2038 tree->right->opval.val : NULL), &tree->args);
2039 TETYPE (tree) = getSpec (TTYPE (tree));
2042 /*------------------------------------------------------------------*/
2043 /*----------------------------*/
2044 /* ++/-- operation */
2045 /*----------------------------*/
2046 case INC_OP: /* incerement operator unary so left only */
2049 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2050 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2051 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
2052 werror (E_CODE_WRITE, "++/--");
2061 /*------------------------------------------------------------------*/
2062 /*----------------------------*/
2064 /*----------------------------*/
2065 case '&': /* can be unary */
2066 /* if right is NULL then unary operation */
2067 if (tree->right) /* not an unary operation */
2070 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2072 werror (E_BITWISE_OP);
2073 werror (E_CONTINUE, "left & right types are ");
2074 printTypeChain (LTYPE (tree), stderr);
2075 fprintf (stderr, ",");
2076 printTypeChain (RTYPE (tree), stderr);
2077 fprintf (stderr, "\n");
2078 goto errorTreeReturn;
2081 /* if they are both literal */
2082 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2084 tree->type = EX_VALUE;
2085 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2086 valFromType (RETYPE (tree)), '&');
2088 tree->right = tree->left = NULL;
2089 TETYPE (tree) = tree->opval.val->etype;
2090 TTYPE (tree) = tree->opval.val->type;
2094 /* see if this is a GETHBIT operation if yes
2097 ast *otree = optimizeGetHbit (tree);
2100 return decorateType (otree);
2104 // we can't do this because of "(int & 0xff) << 3"
2106 /* if right or left is literal then result of that type */
2107 if (IS_LITERAL (RTYPE (tree)))
2110 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2111 TETYPE (tree) = getSpec (TTYPE (tree));
2112 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2116 if (IS_LITERAL (LTYPE (tree)))
2118 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2119 TETYPE (tree) = getSpec (TTYPE (tree));
2120 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2126 computeType (LTYPE (tree), RTYPE (tree));
2127 TETYPE (tree) = getSpec (TTYPE (tree));
2132 computeType (LTYPE (tree), RTYPE (tree));
2133 TETYPE (tree) = getSpec (TTYPE (tree));
2135 LRVAL (tree) = RRVAL (tree) = 1;
2139 /*------------------------------------------------------------------*/
2140 /*----------------------------*/
2142 /*----------------------------*/
2144 p->class = DECLARATOR;
2145 /* if bit field then error */
2146 if (IS_BITVAR (tree->left->etype))
2148 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2149 goto errorTreeReturn;
2152 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2154 werror (E_ILLEGAL_ADDR, "address of register variable");
2155 goto errorTreeReturn;
2158 if (IS_FUNC (LTYPE (tree)))
2160 werror (E_ILLEGAL_ADDR, "address of function");
2161 goto errorTreeReturn;
2166 werror (E_LVALUE_REQUIRED, "address of");
2167 goto errorTreeReturn;
2169 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2171 DCL_TYPE (p) = CPOINTER;
2172 DCL_PTR_CONST (p) = port->mem.code_ro;
2174 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2175 DCL_TYPE (p) = FPOINTER;
2176 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2177 DCL_TYPE (p) = PPOINTER;
2178 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2179 DCL_TYPE (p) = IPOINTER;
2180 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2181 DCL_TYPE (p) = EEPPOINTER;
2183 DCL_TYPE (p) = POINTER;
2185 if (IS_AST_SYM_VALUE (tree->left))
2187 AST_SYMBOL (tree->left)->addrtaken = 1;
2188 AST_SYMBOL (tree->left)->allocreq = 1;
2191 p->next = LTYPE (tree);
2193 TETYPE (tree) = getSpec (TTYPE (tree));
2194 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2195 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2200 /*------------------------------------------------------------------*/
2201 /*----------------------------*/
2203 /*----------------------------*/
2205 /* if the rewrite succeeds then don't go any furthur */
2207 ast *wtree = optimizeRRCRLC (tree);
2209 return decorateType (wtree);
2211 /*------------------------------------------------------------------*/
2212 /*----------------------------*/
2214 /*----------------------------*/
2216 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2218 werror (E_BITWISE_OP);
2219 werror (E_CONTINUE, "left & right types are ");
2220 printTypeChain (LTYPE (tree), stderr);
2221 fprintf (stderr, ",");
2222 printTypeChain (RTYPE (tree), stderr);
2223 fprintf (stderr, "\n");
2224 goto errorTreeReturn;
2227 /* if they are both literal then */
2228 /* rewrite the tree */
2229 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2231 tree->type = EX_VALUE;
2232 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2233 valFromType (RETYPE (tree)),
2235 tree->right = tree->left = NULL;
2236 TETYPE (tree) = tree->opval.val->etype;
2237 TTYPE (tree) = tree->opval.val->type;
2240 LRVAL (tree) = RRVAL (tree) = 1;
2241 TETYPE (tree) = getSpec (TTYPE (tree) =
2242 computeType (LTYPE (tree),
2245 /*------------------------------------------------------------------*/
2246 /*----------------------------*/
2248 /*----------------------------*/
2250 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2252 werror (E_INVALID_OP, "divide");
2253 goto errorTreeReturn;
2255 /* if they are both literal then */
2256 /* rewrite the tree */
2257 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2259 tree->type = EX_VALUE;
2260 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2261 valFromType (RETYPE (tree)));
2262 tree->right = tree->left = NULL;
2263 TETYPE (tree) = getSpec (TTYPE (tree) =
2264 tree->opval.val->type);
2267 LRVAL (tree) = RRVAL (tree) = 1;
2268 TETYPE (tree) = getSpec (TTYPE (tree) =
2269 computeType (LTYPE (tree),
2273 /*------------------------------------------------------------------*/
2274 /*----------------------------*/
2276 /*----------------------------*/
2278 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2280 werror (E_BITWISE_OP);
2281 werror (E_CONTINUE, "left & right types are ");
2282 printTypeChain (LTYPE (tree), stderr);
2283 fprintf (stderr, ",");
2284 printTypeChain (RTYPE (tree), stderr);
2285 fprintf (stderr, "\n");
2286 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 = valMod (valFromType (LETYPE (tree)),
2294 valFromType (RETYPE (tree)));
2295 tree->right = tree->left = NULL;
2296 TETYPE (tree) = getSpec (TTYPE (tree) =
2297 tree->opval.val->type);
2300 LRVAL (tree) = RRVAL (tree) = 1;
2301 TETYPE (tree) = getSpec (TTYPE (tree) =
2302 computeType (LTYPE (tree),
2306 /*------------------------------------------------------------------*/
2307 /*----------------------------*/
2308 /* address dereference */
2309 /*----------------------------*/
2310 case '*': /* can be unary : if right is null then unary operation */
2313 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2315 werror (E_PTR_REQD);
2316 goto errorTreeReturn;
2321 werror (E_LVALUE_REQUIRED, "pointer deref");
2322 goto errorTreeReturn;
2324 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2325 LTYPE (tree)->next : NULL);
2326 TETYPE (tree) = getSpec (TTYPE (tree));
2327 tree->args = tree->left->args;
2328 tree->hasVargs = tree->left->hasVargs;
2329 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2333 /*------------------------------------------------------------------*/
2334 /*----------------------------*/
2335 /* multiplication */
2336 /*----------------------------*/
2337 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2339 werror (E_INVALID_OP, "multiplication");
2340 goto errorTreeReturn;
2343 /* if they are both literal then */
2344 /* rewrite the tree */
2345 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2347 tree->type = EX_VALUE;
2348 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2349 valFromType (RETYPE (tree)));
2350 tree->right = tree->left = NULL;
2351 TETYPE (tree) = getSpec (TTYPE (tree) =
2352 tree->opval.val->type);
2356 /* if left is a literal exchange left & right */
2357 if (IS_LITERAL (LTYPE (tree)))
2359 ast *tTree = tree->left;
2360 tree->left = tree->right;
2361 tree->right = tTree;
2364 LRVAL (tree) = RRVAL (tree) = 1;
2365 /* promote result to int if left & right are char
2366 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2367 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2368 TETYPE (tree) = getSpec (TTYPE (tree) =
2369 computeType (LTYPE (tree),
2371 SPEC_NOUN(TETYPE(tree)) = V_INT;
2373 TETYPE (tree) = getSpec (TTYPE (tree) =
2374 computeType (LTYPE (tree),
2379 /*------------------------------------------------------------------*/
2380 /*----------------------------*/
2381 /* unary '+' operator */
2382 /*----------------------------*/
2387 if (!IS_INTEGRAL (LTYPE (tree)))
2389 werror (E_UNARY_OP, '+');
2390 goto errorTreeReturn;
2393 /* if left is a literal then do it */
2394 if (IS_LITERAL (LTYPE (tree)))
2396 tree->type = EX_VALUE;
2397 tree->opval.val = valFromType (LETYPE (tree));
2399 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2403 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2407 /*------------------------------------------------------------------*/
2408 /*----------------------------*/
2410 /*----------------------------*/
2412 /* this is not a unary operation */
2413 /* if both pointers then problem */
2414 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2415 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2417 werror (E_PTR_PLUS_PTR);
2418 goto errorTreeReturn;
2421 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2422 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2424 werror (E_PLUS_INVALID, "+");
2425 goto errorTreeReturn;
2428 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2429 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2431 werror (E_PLUS_INVALID, "+");
2432 goto errorTreeReturn;
2434 /* if they are both literal then */
2435 /* rewrite the tree */
2436 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2438 tree->type = EX_VALUE;
2439 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2440 valFromType (RETYPE (tree)));
2441 tree->right = tree->left = NULL;
2442 TETYPE (tree) = getSpec (TTYPE (tree) =
2443 tree->opval.val->type);
2447 /* if the right is a pointer or left is a literal
2448 xchange left & right */
2449 if (IS_ARRAY (RTYPE (tree)) ||
2450 IS_PTR (RTYPE (tree)) ||
2451 IS_LITERAL (LTYPE (tree)))
2453 ast *tTree = tree->left;
2454 tree->left = tree->right;
2455 tree->right = tTree;
2458 LRVAL (tree) = RRVAL (tree) = 1;
2459 /* if the left is a pointer */
2460 if (IS_PTR (LTYPE (tree)))
2461 TETYPE (tree) = getSpec (TTYPE (tree) =
2464 TETYPE (tree) = getSpec (TTYPE (tree) =
2465 computeType (LTYPE (tree),
2469 /*------------------------------------------------------------------*/
2470 /*----------------------------*/
2472 /*----------------------------*/
2473 case '-': /* can be unary */
2474 /* if right is null then unary */
2478 if (!IS_ARITHMETIC (LTYPE (tree)))
2480 werror (E_UNARY_OP, tree->opval.op);
2481 goto errorTreeReturn;
2484 /* if left is a literal then do it */
2485 if (IS_LITERAL (LTYPE (tree)))
2487 tree->type = EX_VALUE;
2488 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2490 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2491 SPEC_USIGN(TETYPE(tree)) = 0;
2495 TTYPE (tree) = LTYPE (tree);
2499 /*------------------------------------------------------------------*/
2500 /*----------------------------*/
2502 /*----------------------------*/
2504 if (!(IS_PTR (LTYPE (tree)) ||
2505 IS_ARRAY (LTYPE (tree)) ||
2506 IS_ARITHMETIC (LTYPE (tree))))
2508 werror (E_PLUS_INVALID, "-");
2509 goto errorTreeReturn;
2512 if (!(IS_PTR (RTYPE (tree)) ||
2513 IS_ARRAY (RTYPE (tree)) ||
2514 IS_ARITHMETIC (RTYPE (tree))))
2516 werror (E_PLUS_INVALID, "-");
2517 goto errorTreeReturn;
2520 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2521 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2522 IS_INTEGRAL (RTYPE (tree))))
2524 werror (E_PLUS_INVALID, "-");
2525 goto errorTreeReturn;
2528 /* if they are both literal then */
2529 /* rewrite the tree */
2530 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2532 tree->type = EX_VALUE;
2533 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2534 valFromType (RETYPE (tree)));
2535 tree->right = tree->left = NULL;
2536 TETYPE (tree) = getSpec (TTYPE (tree) =
2537 tree->opval.val->type);
2541 /* if the left & right are equal then zero */
2542 if (isAstEqual (tree->left, tree->right))
2544 tree->type = EX_VALUE;
2545 tree->left = tree->right = NULL;
2546 tree->opval.val = constVal ("0");
2547 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2551 /* if both of them are pointers or arrays then */
2552 /* the result is going to be an integer */
2553 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2554 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2555 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2557 /* if only the left is a pointer */
2558 /* then result is a pointer */
2559 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2560 TETYPE (tree) = getSpec (TTYPE (tree) =
2563 TETYPE (tree) = getSpec (TTYPE (tree) =
2564 computeType (LTYPE (tree),
2566 LRVAL (tree) = RRVAL (tree) = 1;
2569 /*------------------------------------------------------------------*/
2570 /*----------------------------*/
2572 /*----------------------------*/
2574 /* can be only integral type */
2575 if (!IS_INTEGRAL (LTYPE (tree)))
2577 werror (E_UNARY_OP, tree->opval.op);
2578 goto errorTreeReturn;
2581 /* if left is a literal then do it */
2582 if (IS_LITERAL (LTYPE (tree)))
2584 tree->type = EX_VALUE;
2585 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2587 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2591 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2594 /*------------------------------------------------------------------*/
2595 /*----------------------------*/
2597 /*----------------------------*/
2599 /* can be pointer */
2600 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2601 !IS_PTR (LTYPE (tree)) &&
2602 !IS_ARRAY (LTYPE (tree)))
2604 werror (E_UNARY_OP, tree->opval.op);
2605 goto errorTreeReturn;
2608 /* if left is a literal then do it */
2609 if (IS_LITERAL (LTYPE (tree)))
2611 tree->type = EX_VALUE;
2612 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2614 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2618 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2621 /*------------------------------------------------------------------*/
2622 /*----------------------------*/
2624 /*----------------------------*/
2627 TTYPE (tree) = LTYPE (tree);
2628 TETYPE (tree) = LETYPE (tree);
2632 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2637 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2639 werror (E_SHIFT_OP_INVALID);
2640 werror (E_CONTINUE, "left & right types are ");
2641 printTypeChain (LTYPE (tree), stderr);
2642 fprintf (stderr, ",");
2643 printTypeChain (RTYPE (tree), stderr);
2644 fprintf (stderr, "\n");
2645 goto errorTreeReturn;
2648 /* if they are both literal then */
2649 /* rewrite the tree */
2650 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2652 tree->type = EX_VALUE;
2653 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2654 valFromType (RETYPE (tree)),
2655 (tree->opval.op == LEFT_OP ? 1 : 0));
2656 tree->right = tree->left = NULL;
2657 TETYPE (tree) = getSpec (TTYPE (tree) =
2658 tree->opval.val->type);
2661 /* if only the right side is a literal & we are
2662 shifting more than size of the left operand then zero */
2663 if (IS_LITERAL (RTYPE (tree)) &&
2664 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2665 (getSize (LTYPE (tree)) * 8))
2667 werror (W_SHIFT_CHANGED,
2668 (tree->opval.op == LEFT_OP ? "left" : "right"));
2669 tree->type = EX_VALUE;
2670 tree->left = tree->right = NULL;
2671 tree->opval.val = constVal ("0");
2672 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2675 LRVAL (tree) = RRVAL (tree) = 1;
2676 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2678 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2682 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2686 /*------------------------------------------------------------------*/
2687 /*----------------------------*/
2689 /*----------------------------*/
2690 case CAST: /* change the type */
2691 /* cannot cast to an aggregate type */
2692 if (IS_AGGREGATE (LTYPE (tree)))
2694 werror (E_CAST_ILLEGAL);
2695 goto errorTreeReturn;
2698 /* make sure the type is complete and sane */
2699 checkTypeSanity(LETYPE(tree), "(cast)");
2701 /* if the right is a literal replace the tree */
2702 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2704 tree->type = EX_VALUE;
2706 valCastLiteral (LTYPE (tree),
2707 floatFromVal (valFromType (RETYPE (tree))));
2710 TTYPE (tree) = tree->opval.val->type;
2711 tree->values.literalFromCast = 1;
2715 TTYPE (tree) = LTYPE (tree);
2719 TETYPE (tree) = getSpec (TTYPE (tree));
2723 /*------------------------------------------------------------------*/
2724 /*----------------------------*/
2725 /* logical &&, || */
2726 /*----------------------------*/
2729 /* each must me arithmetic type or be a pointer */
2730 if (!IS_PTR (LTYPE (tree)) &&
2731 !IS_ARRAY (LTYPE (tree)) &&
2732 !IS_INTEGRAL (LTYPE (tree)))
2734 werror (E_COMPARE_OP);
2735 goto errorTreeReturn;
2738 if (!IS_PTR (RTYPE (tree)) &&
2739 !IS_ARRAY (RTYPE (tree)) &&
2740 !IS_INTEGRAL (RTYPE (tree)))
2742 werror (E_COMPARE_OP);
2743 goto errorTreeReturn;
2745 /* if they are both literal then */
2746 /* rewrite the tree */
2747 if (IS_LITERAL (RTYPE (tree)) &&
2748 IS_LITERAL (LTYPE (tree)))
2750 tree->type = EX_VALUE;
2751 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2752 valFromType (RETYPE (tree)),
2754 tree->right = tree->left = NULL;
2755 TETYPE (tree) = getSpec (TTYPE (tree) =
2756 tree->opval.val->type);
2759 LRVAL (tree) = RRVAL (tree) = 1;
2760 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2763 /*------------------------------------------------------------------*/
2764 /*----------------------------*/
2765 /* comparison operators */
2766 /*----------------------------*/
2774 ast *lt = optimizeCompare (tree);
2780 /* if they are pointers they must be castable */
2781 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2783 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2785 werror (E_COMPARE_OP);
2786 fprintf (stderr, "comparing type ");
2787 printTypeChain (LTYPE (tree), stderr);
2788 fprintf (stderr, "to type ");
2789 printTypeChain (RTYPE (tree), stderr);
2790 fprintf (stderr, "\n");
2791 goto errorTreeReturn;
2794 /* else they should be promotable to one another */
2797 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2798 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2800 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2802 werror (E_COMPARE_OP);
2803 fprintf (stderr, "comparing type ");
2804 printTypeChain (LTYPE (tree), stderr);
2805 fprintf (stderr, "to type ");
2806 printTypeChain (RTYPE (tree), stderr);
2807 fprintf (stderr, "\n");
2808 goto errorTreeReturn;
2812 /* if they are both literal then */
2813 /* rewrite the tree */
2814 if (IS_LITERAL (RTYPE (tree)) &&
2815 IS_LITERAL (LTYPE (tree)))
2817 tree->type = EX_VALUE;
2818 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2819 valFromType (RETYPE (tree)),
2821 tree->right = tree->left = NULL;
2822 TETYPE (tree) = getSpec (TTYPE (tree) =
2823 tree->opval.val->type);
2826 LRVAL (tree) = RRVAL (tree) = 1;
2827 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2830 /*------------------------------------------------------------------*/
2831 /*----------------------------*/
2833 /*----------------------------*/
2834 case SIZEOF: /* evaluate wihout code generation */
2835 /* change the type to a integer */
2836 tree->type = EX_VALUE;
2837 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2838 tree->opval.val = constVal (buffer);
2839 tree->right = tree->left = NULL;
2840 TETYPE (tree) = getSpec (TTYPE (tree) =
2841 tree->opval.val->type);
2844 /*------------------------------------------------------------------*/
2845 /*----------------------------*/
2846 /* conditional operator '?' */
2847 /*----------------------------*/
2849 /* the type is value of the colon operator (on the right) */
2850 assert(IS_COLON_OP(tree->right));
2851 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2852 TETYPE (tree) = getSpec (TTYPE (tree));
2856 /* if they don't match we have a problem */
2857 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2859 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2860 goto errorTreeReturn;
2863 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2864 TETYPE (tree) = getSpec (TTYPE (tree));
2868 /*------------------------------------------------------------------*/
2869 /*----------------------------*/
2870 /* assignment operators */
2871 /*----------------------------*/
2874 /* for these it must be both must be integral */
2875 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2876 !IS_ARITHMETIC (RTYPE (tree)))
2878 werror (E_OPS_INTEGRAL);
2879 goto errorTreeReturn;
2882 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2884 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2885 werror (E_CODE_WRITE, " ");
2889 werror (E_LVALUE_REQUIRED, "*= or /=");
2890 goto errorTreeReturn;
2903 /* for these it must be both must be integral */
2904 if (!IS_INTEGRAL (LTYPE (tree)) ||
2905 !IS_INTEGRAL (RTYPE (tree)))
2907 werror (E_OPS_INTEGRAL);
2908 goto errorTreeReturn;
2911 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2913 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2914 werror (E_CODE_WRITE, " ");
2918 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2919 goto errorTreeReturn;
2927 /*------------------------------------------------------------------*/
2928 /*----------------------------*/
2930 /*----------------------------*/
2932 if (!(IS_PTR (LTYPE (tree)) ||
2933 IS_ARITHMETIC (LTYPE (tree))))
2935 werror (E_PLUS_INVALID, "-=");
2936 goto errorTreeReturn;
2939 if (!(IS_PTR (RTYPE (tree)) ||
2940 IS_ARITHMETIC (RTYPE (tree))))
2942 werror (E_PLUS_INVALID, "-=");
2943 goto errorTreeReturn;
2946 TETYPE (tree) = getSpec (TTYPE (tree) =
2947 computeType (LTYPE (tree),
2950 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2951 werror (E_CODE_WRITE, " ");
2955 werror (E_LVALUE_REQUIRED, "-=");
2956 goto errorTreeReturn;
2964 /*------------------------------------------------------------------*/
2965 /*----------------------------*/
2967 /*----------------------------*/
2969 /* this is not a unary operation */
2970 /* if both pointers then problem */
2971 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2973 werror (E_PTR_PLUS_PTR);
2974 goto errorTreeReturn;
2977 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2979 werror (E_PLUS_INVALID, "+=");
2980 goto errorTreeReturn;
2983 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2985 werror (E_PLUS_INVALID, "+=");
2986 goto errorTreeReturn;
2989 TETYPE (tree) = getSpec (TTYPE (tree) =
2990 computeType (LTYPE (tree),
2993 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2994 werror (E_CODE_WRITE, " ");
2998 werror (E_LVALUE_REQUIRED, "+=");
2999 goto errorTreeReturn;
3002 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3003 tree->opval.op = '=';
3009 /*------------------------------------------------------------------*/
3010 /*----------------------------*/
3011 /* straight assignemnt */
3012 /*----------------------------*/
3014 /* cannot be an aggregate */
3015 if (IS_AGGREGATE (LTYPE (tree)))
3017 werror (E_AGGR_ASSIGN);
3018 goto errorTreeReturn;
3021 /* they should either match or be castable */
3022 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3024 werror (E_TYPE_MISMATCH, "assignment", " ");
3025 fprintf (stderr, "type --> '");
3026 printTypeChain (RTYPE (tree), stderr);
3027 fprintf (stderr, "' ");
3028 fprintf (stderr, "assigned to type --> '");
3029 printTypeChain (LTYPE (tree), stderr);
3030 fprintf (stderr, "'\n");
3031 goto errorTreeReturn;
3034 /* if the left side of the tree is of type void
3035 then report error */
3036 if (IS_VOID (LTYPE (tree)))
3038 werror (E_CAST_ZERO);
3039 fprintf (stderr, "type --> '");
3040 printTypeChain (RTYPE (tree), stderr);
3041 fprintf (stderr, "' ");
3042 fprintf (stderr, "assigned to type --> '");
3043 printTypeChain (LTYPE (tree), stderr);
3044 fprintf (stderr, "'\n");
3047 /* extra checks for pointer types */
3048 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
3049 !IS_GENPTR (LTYPE (tree)))
3051 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
3052 werror (W_PTR_ASSIGN);
3055 TETYPE (tree) = getSpec (TTYPE (tree) =
3059 if (!tree->initMode ) {
3060 if (IS_CONSTANT (LETYPE (tree))) {
3061 werror (E_CODE_WRITE, " ");
3066 werror (E_LVALUE_REQUIRED, "=");
3067 goto errorTreeReturn;
3074 /*------------------------------------------------------------------*/
3075 /*----------------------------*/
3076 /* comma operator */
3077 /*----------------------------*/
3079 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3082 /*------------------------------------------------------------------*/
3083 /*----------------------------*/
3085 /*----------------------------*/
3089 if (processParms (tree->left,
3091 tree->right, &parmNumber, TRUE))
3092 goto errorTreeReturn;
3094 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3096 tree->left->args = reverseVal (tree->left->args);
3097 reverseParms (tree->right);
3100 tree->args = tree->left->args;
3101 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3104 /*------------------------------------------------------------------*/
3105 /*----------------------------*/
3106 /* return statement */
3107 /*----------------------------*/
3112 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3114 werror (E_RETURN_MISMATCH);
3115 goto errorTreeReturn;
3118 if (IS_VOID (currFunc->type->next)
3120 !IS_VOID (RTYPE (tree)))
3122 werror (E_FUNC_VOID);
3123 goto errorTreeReturn;
3126 /* if there is going to be a casing required then add it */
3127 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3129 #if 0 && defined DEMAND_INTEGER_PROMOTION
3130 if (IS_INTEGRAL (currFunc->type->next))
3132 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3138 decorateType (newNode (CAST,
3139 newAst_LINK (copyLinkChain (currFunc->type->next)),
3149 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3151 werror (E_VOID_FUNC, currFunc->name);
3152 goto errorTreeReturn;
3155 TTYPE (tree) = TETYPE (tree) = NULL;
3158 /*------------------------------------------------------------------*/
3159 /*----------------------------*/
3160 /* switch statement */
3161 /*----------------------------*/
3163 /* the switch value must be an integer */
3164 if (!IS_INTEGRAL (LTYPE (tree)))
3166 werror (E_SWITCH_NON_INTEGER);
3167 goto errorTreeReturn;
3170 TTYPE (tree) = TETYPE (tree) = NULL;
3173 /*------------------------------------------------------------------*/
3174 /*----------------------------*/
3176 /*----------------------------*/
3178 tree->left = backPatchLabels (tree->left,
3181 TTYPE (tree) = TETYPE (tree) = NULL;
3184 /*------------------------------------------------------------------*/
3185 /*----------------------------*/
3187 /*----------------------------*/
3190 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3191 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3192 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3194 /* if the for loop is reversible then
3195 reverse it otherwise do what we normally
3201 if (isLoopReversible (tree, &sym, &init, &end))
3202 return reverseLoop (tree, sym, init, end);
3204 return decorateType (createFor (AST_FOR (tree, trueLabel),
3205 AST_FOR (tree, continueLabel),
3206 AST_FOR (tree, falseLabel),
3207 AST_FOR (tree, condLabel),
3208 AST_FOR (tree, initExpr),
3209 AST_FOR (tree, condExpr),
3210 AST_FOR (tree, loopExpr),
3214 TTYPE (tree) = TETYPE (tree) = NULL;
3218 /* some error found this tree will be killed */
3220 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3221 tree->opval.op = NULLOP;
3227 /*-----------------------------------------------------------------*/
3228 /* sizeofOp - processes size of operation */
3229 /*-----------------------------------------------------------------*/
3231 sizeofOp (sym_link * type)
3235 /* make sure the type is complete and sane */
3236 checkTypeSanity(type, "(sizeof)");
3238 /* get the size and convert it to character */
3239 sprintf (buff, "%d", getSize (type));
3241 /* now convert into value */
3242 return constVal (buff);
3246 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3247 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3248 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3249 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3250 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3251 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3252 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3254 /*-----------------------------------------------------------------*/
3255 /* backPatchLabels - change and or not operators to flow control */
3256 /*-----------------------------------------------------------------*/
3258 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3264 if (!(IS_ANDORNOT (tree)))
3267 /* if this an and */
3270 static int localLbl = 0;
3273 sprintf (buffer, "_and_%d", localLbl++);
3274 localLabel = newSymbol (buffer, NestLevel);
3276 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3278 /* if left is already a IFX then just change the if true label in that */
3279 if (!IS_IFX (tree->left))
3280 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3282 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3283 /* right is a IFX then just join */
3284 if (IS_IFX (tree->right))
3285 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3287 tree->right = createLabel (localLabel, tree->right);
3288 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3290 return newNode (NULLOP, tree->left, tree->right);
3293 /* if this is an or operation */
3296 static int localLbl = 0;
3299 sprintf (buffer, "_or_%d", localLbl++);
3300 localLabel = newSymbol (buffer, NestLevel);
3302 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3304 /* if left is already a IFX then just change the if true label in that */
3305 if (!IS_IFX (tree->left))
3306 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3308 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3309 /* right is a IFX then just join */
3310 if (IS_IFX (tree->right))
3311 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3313 tree->right = createLabel (localLabel, tree->right);
3314 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3316 return newNode (NULLOP, tree->left, tree->right);
3322 int wasnot = IS_NOT (tree->left);
3323 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3325 /* if the left is already a IFX */
3326 if (!IS_IFX (tree->left))
3327 tree->left = newNode (IFX, tree->left, NULL);
3331 tree->left->trueLabel = trueLabel;
3332 tree->left->falseLabel = falseLabel;
3336 tree->left->trueLabel = falseLabel;
3337 tree->left->falseLabel = trueLabel;
3344 tree->trueLabel = trueLabel;
3345 tree->falseLabel = falseLabel;
3352 /*-----------------------------------------------------------------*/
3353 /* createBlock - create expression tree for block */
3354 /*-----------------------------------------------------------------*/
3356 createBlock (symbol * decl, ast * body)
3360 /* if the block has nothing */
3364 ex = newNode (BLOCK, NULL, body);
3365 ex->values.sym = decl;
3367 ex->right = ex->right;
3373 /*-----------------------------------------------------------------*/
3374 /* createLabel - creates the expression tree for labels */
3375 /*-----------------------------------------------------------------*/
3377 createLabel (symbol * label, ast * stmnt)
3380 char name[SDCC_NAME_MAX + 1];
3383 /* must create fresh symbol if the symbol name */
3384 /* exists in the symbol table, since there can */
3385 /* be a variable with the same name as the labl */
3386 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3387 (csym->level == label->level))
3388 label = newSymbol (label->name, label->level);
3390 /* change the name before putting it in add _ */
3391 sprintf (name, "%s", label->name);
3393 /* put the label in the LabelSymbol table */
3394 /* but first check if a label of the same */
3396 if ((csym = findSym (LabelTab, NULL, name)))
3397 werror (E_DUPLICATE_LABEL, label->name);
3399 addSym (LabelTab, label, name, label->level, 0, 0);
3402 label->key = labelKey++;
3403 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3409 /*-----------------------------------------------------------------*/
3410 /* createCase - generates the parsetree for a case statement */
3411 /*-----------------------------------------------------------------*/
3413 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3415 char caseLbl[SDCC_NAME_MAX + 1];
3419 /* if the switch statement does not exist */
3420 /* then case is out of context */
3423 werror (E_CASE_CONTEXT);
3427 caseVal = decorateType (resolveSymbols (caseVal));
3428 /* if not a constant then error */
3429 if (!IS_LITERAL (caseVal->ftype))
3431 werror (E_CASE_CONSTANT);
3435 /* if not a integer than error */
3436 if (!IS_INTEGRAL (caseVal->ftype))
3438 werror (E_CASE_NON_INTEGER);
3442 /* find the end of the switch values chain */
3443 if (!(val = swStat->values.switchVals.swVals))
3444 swStat->values.switchVals.swVals = caseVal->opval.val;
3447 /* also order the cases according to value */
3449 int cVal = (int) floatFromVal (caseVal->opval.val);
3450 while (val && (int) floatFromVal (val) < cVal)
3456 /* if we reached the end then */
3459 pval->next = caseVal->opval.val;
3463 /* we found a value greater than */
3464 /* the current value we must add this */
3465 /* before the value */
3466 caseVal->opval.val->next = val;
3468 /* if this was the first in chain */
3469 if (swStat->values.switchVals.swVals == val)
3470 swStat->values.switchVals.swVals =
3473 pval->next = caseVal->opval.val;
3478 /* create the case label */
3479 sprintf (caseLbl, "_case_%d_%d",
3480 swStat->values.switchVals.swNum,
3481 (int) floatFromVal (caseVal->opval.val));
3483 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3488 /*-----------------------------------------------------------------*/
3489 /* createDefault - creates the parse tree for the default statement */
3490 /*-----------------------------------------------------------------*/
3492 createDefault (ast * swStat, ast * stmnt)
3494 char defLbl[SDCC_NAME_MAX + 1];
3496 /* if the switch statement does not exist */
3497 /* then case is out of context */
3500 werror (E_CASE_CONTEXT);
3504 /* turn on the default flag */
3505 swStat->values.switchVals.swDefault = 1;
3507 /* create the label */
3508 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3509 return createLabel (newSymbol (defLbl, 0), stmnt);
3512 /*-----------------------------------------------------------------*/
3513 /* createIf - creates the parsetree for the if statement */
3514 /*-----------------------------------------------------------------*/
3516 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3518 static int Lblnum = 0;
3520 symbol *ifTrue, *ifFalse, *ifEnd;
3522 /* if neither exists */
3523 if (!elseBody && !ifBody)
3526 /* create the labels */
3527 sprintf (buffer, "_iffalse_%d", Lblnum);
3528 ifFalse = newSymbol (buffer, NestLevel);
3529 /* if no else body then end == false */
3534 sprintf (buffer, "_ifend_%d", Lblnum);
3535 ifEnd = newSymbol (buffer, NestLevel);
3538 sprintf (buffer, "_iftrue_%d", Lblnum);
3539 ifTrue = newSymbol (buffer, NestLevel);
3543 /* attach the ifTrue label to the top of it body */
3544 ifBody = createLabel (ifTrue, ifBody);
3545 /* attach a goto end to the ifBody if else is present */
3548 ifBody = newNode (NULLOP, ifBody,
3550 newAst_VALUE (symbolVal (ifEnd)),
3552 /* put the elseLabel on the else body */
3553 elseBody = createLabel (ifFalse, elseBody);
3554 /* out the end at the end of the body */
3555 elseBody = newNode (NULLOP,
3557 createLabel (ifEnd, NULL));
3561 ifBody = newNode (NULLOP, ifBody,
3562 createLabel (ifFalse, NULL));
3564 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3565 if (IS_IFX (condAst))
3568 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3570 return newNode (NULLOP, ifTree,
3571 newNode (NULLOP, ifBody, elseBody));
3575 /*-----------------------------------------------------------------*/
3576 /* createDo - creates parse tree for do */
3579 /* _docontinue_n: */
3580 /* condition_expression +-> trueLabel -> _dobody_n */
3582 /* +-> falseLabel-> _dobreak_n */
3584 /*-----------------------------------------------------------------*/
3586 createDo (symbol * trueLabel, symbol * continueLabel,
3587 symbol * falseLabel, ast * condAst, ast * doBody)
3592 /* if the body does not exist then it is simple */
3595 condAst = backPatchLabels (condAst, continueLabel, NULL);
3596 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3597 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3598 doTree->trueLabel = continueLabel;
3599 doTree->falseLabel = NULL;
3603 /* otherwise we have a body */
3604 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3606 /* attach the body label to the top */
3607 doBody = createLabel (trueLabel, doBody);
3608 /* attach the continue label to end of body */
3609 doBody = newNode (NULLOP, doBody,
3610 createLabel (continueLabel, NULL));
3612 /* now put the break label at the end */
3613 if (IS_IFX (condAst))
3616 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3618 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3620 /* putting it together */
3621 return newNode (NULLOP, doBody, doTree);
3624 /*-----------------------------------------------------------------*/
3625 /* createFor - creates parse tree for 'for' statement */
3628 /* condExpr +-> trueLabel -> _forbody_n */
3630 /* +-> falseLabel-> _forbreak_n */
3633 /* _forcontinue_n: */
3635 /* goto _forcond_n ; */
3637 /*-----------------------------------------------------------------*/
3639 createFor (symbol * trueLabel, symbol * continueLabel,
3640 symbol * falseLabel, symbol * condLabel,
3641 ast * initExpr, ast * condExpr, ast * loopExpr,
3646 /* if loopexpression not present then we can generate it */
3647 /* the same way as a while */
3649 return newNode (NULLOP, initExpr,
3650 createWhile (trueLabel, continueLabel,
3651 falseLabel, condExpr, forBody));
3652 /* vanilla for statement */
3653 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3655 if (condExpr && !IS_IFX (condExpr))
3656 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3659 /* attach condition label to condition */
3660 condExpr = createLabel (condLabel, condExpr);
3662 /* attach body label to body */
3663 forBody = createLabel (trueLabel, forBody);
3665 /* attach continue to forLoop expression & attach */
3666 /* goto the forcond @ and of loopExpression */
3667 loopExpr = createLabel (continueLabel,
3671 newAst_VALUE (symbolVal (condLabel)),
3673 /* now start putting them together */
3674 forTree = newNode (NULLOP, initExpr, condExpr);
3675 forTree = newNode (NULLOP, forTree, forBody);
3676 forTree = newNode (NULLOP, forTree, loopExpr);
3677 /* finally add the break label */
3678 forTree = newNode (NULLOP, forTree,
3679 createLabel (falseLabel, NULL));
3683 /*-----------------------------------------------------------------*/
3684 /* createWhile - creates parse tree for while statement */
3685 /* the while statement will be created as follows */
3687 /* _while_continue_n: */
3688 /* condition_expression +-> trueLabel -> _while_boby_n */
3690 /* +-> falseLabel -> _while_break_n */
3691 /* _while_body_n: */
3693 /* goto _while_continue_n */
3694 /* _while_break_n: */
3695 /*-----------------------------------------------------------------*/
3697 createWhile (symbol * trueLabel, symbol * continueLabel,
3698 symbol * falseLabel, ast * condExpr, ast * whileBody)
3702 /* put the continue label */
3703 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3704 condExpr = createLabel (continueLabel, condExpr);
3705 condExpr->lineno = 0;
3707 /* put the body label in front of the body */
3708 whileBody = createLabel (trueLabel, whileBody);
3709 whileBody->lineno = 0;
3710 /* put a jump to continue at the end of the body */
3711 /* and put break label at the end of the body */
3712 whileBody = newNode (NULLOP,
3715 newAst_VALUE (symbolVal (continueLabel)),
3716 createLabel (falseLabel, NULL)));
3718 /* put it all together */
3719 if (IS_IFX (condExpr))
3720 whileTree = condExpr;
3723 whileTree = newNode (IFX, condExpr, NULL);
3724 /* put the true & false labels in place */
3725 whileTree->trueLabel = trueLabel;
3726 whileTree->falseLabel = falseLabel;
3729 return newNode (NULLOP, whileTree, whileBody);
3732 /*-----------------------------------------------------------------*/
3733 /* optimizeGetHbit - get highest order bit of the expression */
3734 /*-----------------------------------------------------------------*/
3736 optimizeGetHbit (ast * tree)
3739 /* if this is not a bit and */
3740 if (!IS_BITAND (tree))
3743 /* will look for tree of the form
3744 ( expr >> ((sizeof expr) -1) ) & 1 */
3745 if (!IS_AST_LIT_VALUE (tree->right))
3748 if (AST_LIT_VALUE (tree->right) != 1)
3751 if (!IS_RIGHT_OP (tree->left))
3754 if (!IS_AST_LIT_VALUE (tree->left->right))
3757 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3758 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3761 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3765 /*-----------------------------------------------------------------*/
3766 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3767 /*-----------------------------------------------------------------*/
3769 optimizeRRCRLC (ast * root)
3771 /* will look for trees of the form
3772 (?expr << 1) | (?expr >> 7) or
3773 (?expr >> 7) | (?expr << 1) will make that
3774 into a RLC : operation ..
3776 (?expr >> 1) | (?expr << 7) or
3777 (?expr << 7) | (?expr >> 1) will make that
3778 into a RRC operation
3779 note : by 7 I mean (number of bits required to hold the
3781 /* if the root operations is not a | operation the not */
3782 if (!IS_BITOR (root))
3785 /* I have to think of a better way to match patterns this sucks */
3786 /* that aside let start looking for the first case : I use a the
3787 negative check a lot to improve the efficiency */
3788 /* (?expr << 1) | (?expr >> 7) */
3789 if (IS_LEFT_OP (root->left) &&
3790 IS_RIGHT_OP (root->right))
3793 if (!SPEC_USIGN (TETYPE (root->left->left)))
3796 if (!IS_AST_LIT_VALUE (root->left->right) ||
3797 !IS_AST_LIT_VALUE (root->right->right))
3800 /* make sure it is the same expression */
3801 if (!isAstEqual (root->left->left,
3805 if (AST_LIT_VALUE (root->left->right) != 1)
3808 if (AST_LIT_VALUE (root->right->right) !=
3809 (getSize (TTYPE (root->left->left)) * 8 - 1))
3812 /* whew got the first case : create the AST */
3813 return newNode (RLC, root->left->left, NULL);
3817 /* check for second case */
3818 /* (?expr >> 7) | (?expr << 1) */
3819 if (IS_LEFT_OP (root->right) &&
3820 IS_RIGHT_OP (root->left))
3823 if (!SPEC_USIGN (TETYPE (root->left->left)))
3826 if (!IS_AST_LIT_VALUE (root->left->right) ||
3827 !IS_AST_LIT_VALUE (root->right->right))
3830 /* make sure it is the same symbol */
3831 if (!isAstEqual (root->left->left,
3835 if (AST_LIT_VALUE (root->right->right) != 1)
3838 if (AST_LIT_VALUE (root->left->right) !=
3839 (getSize (TTYPE (root->left->left)) * 8 - 1))
3842 /* whew got the first case : create the AST */
3843 return newNode (RLC, root->left->left, NULL);
3848 /* third case for RRC */
3849 /* (?symbol >> 1) | (?symbol << 7) */
3850 if (IS_LEFT_OP (root->right) &&
3851 IS_RIGHT_OP (root->left))
3854 if (!SPEC_USIGN (TETYPE (root->left->left)))
3857 if (!IS_AST_LIT_VALUE (root->left->right) ||
3858 !IS_AST_LIT_VALUE (root->right->right))
3861 /* make sure it is the same symbol */
3862 if (!isAstEqual (root->left->left,
3866 if (AST_LIT_VALUE (root->left->right) != 1)
3869 if (AST_LIT_VALUE (root->right->right) !=
3870 (getSize (TTYPE (root->left->left)) * 8 - 1))
3873 /* whew got the first case : create the AST */
3874 return newNode (RRC, root->left->left, NULL);
3878 /* fourth and last case for now */
3879 /* (?symbol << 7) | (?symbol >> 1) */
3880 if (IS_RIGHT_OP (root->right) &&
3881 IS_LEFT_OP (root->left))
3884 if (!SPEC_USIGN (TETYPE (root->left->left)))
3887 if (!IS_AST_LIT_VALUE (root->left->right) ||
3888 !IS_AST_LIT_VALUE (root->right->right))
3891 /* make sure it is the same symbol */
3892 if (!isAstEqual (root->left->left,
3896 if (AST_LIT_VALUE (root->right->right) != 1)
3899 if (AST_LIT_VALUE (root->left->right) !=
3900 (getSize (TTYPE (root->left->left)) * 8 - 1))
3903 /* whew got the first case : create the AST */
3904 return newNode (RRC, root->left->left, NULL);
3908 /* not found return root */
3912 /*-----------------------------------------------------------------*/
3913 /* optimizeCompare - otimizes compares for bit variables */
3914 /*-----------------------------------------------------------------*/
3916 optimizeCompare (ast * root)
3918 ast *optExpr = NULL;
3921 unsigned int litValue;
3923 /* if nothing then return nothing */
3927 /* if not a compare op then do leaves */
3928 if (!IS_COMPARE_OP (root))
3930 root->left = optimizeCompare (root->left);
3931 root->right = optimizeCompare (root->right);
3935 /* if left & right are the same then depending
3936 of the operation do */
3937 if (isAstEqual (root->left, root->right))
3939 switch (root->opval.op)
3944 optExpr = newAst_VALUE (constVal ("0"));
3949 optExpr = newAst_VALUE (constVal ("1"));
3953 return decorateType (optExpr);
3956 vleft = (root->left->type == EX_VALUE ?
3957 root->left->opval.val : NULL);
3959 vright = (root->right->type == EX_VALUE ?
3960 root->right->opval.val : NULL);
3962 /* if left is a BITVAR in BITSPACE */
3963 /* and right is a LITERAL then opt- */
3964 /* imize else do nothing */
3965 if (vleft && vright &&
3966 IS_BITVAR (vleft->etype) &&
3967 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3968 IS_LITERAL (vright->etype))
3971 /* if right side > 1 then comparison may never succeed */
3972 if ((litValue = (int) floatFromVal (vright)) > 1)
3974 werror (W_BAD_COMPARE);
3980 switch (root->opval.op)
3982 case '>': /* bit value greater than 1 cannot be */
3983 werror (W_BAD_COMPARE);
3987 case '<': /* bit value < 1 means 0 */
3989 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3992 case LE_OP: /* bit value <= 1 means no check */
3993 optExpr = newAst_VALUE (vright);
3996 case GE_OP: /* bit value >= 1 means only check for = */
3998 optExpr = newAst_VALUE (vleft);
4003 { /* literal is zero */
4004 switch (root->opval.op)
4006 case '<': /* bit value < 0 cannot be */
4007 werror (W_BAD_COMPARE);
4011 case '>': /* bit value > 0 means 1 */
4013 optExpr = newAst_VALUE (vleft);
4016 case LE_OP: /* bit value <= 0 means no check */
4017 case GE_OP: /* bit value >= 0 means no check */
4018 werror (W_BAD_COMPARE);
4022 case EQ_OP: /* bit == 0 means ! of bit */
4023 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4027 return decorateType (resolveSymbols (optExpr));
4028 } /* end-of-if of BITVAR */
4033 /*-----------------------------------------------------------------*/
4034 /* addSymToBlock : adds the symbol to the first block we find */
4035 /*-----------------------------------------------------------------*/
4037 addSymToBlock (symbol * sym, ast * tree)
4039 /* reached end of tree or a leaf */
4040 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4044 if (IS_AST_OP (tree) &&
4045 tree->opval.op == BLOCK)
4048 symbol *lsym = copySymbol (sym);
4050 lsym->next = AST_VALUES (tree, sym);
4051 AST_VALUES (tree, sym) = lsym;
4055 addSymToBlock (sym, tree->left);
4056 addSymToBlock (sym, tree->right);
4059 /*-----------------------------------------------------------------*/
4060 /* processRegParms - do processing for register parameters */
4061 /*-----------------------------------------------------------------*/
4063 processRegParms (value * args, ast * body)
4067 if (IS_REGPARM (args->etype))
4068 addSymToBlock (args->sym, body);
4073 /*-----------------------------------------------------------------*/
4074 /* resetParmKey - resets the operandkeys for the symbols */
4075 /*-----------------------------------------------------------------*/
4076 DEFSETFUNC (resetParmKey)
4087 /*-----------------------------------------------------------------*/
4088 /* createFunction - This is the key node that calls the iCode for */
4089 /* generating the code for a function. Note code */
4090 /* is generated function by function, later when */
4091 /* add inter-procedural analysis this will change */
4092 /*-----------------------------------------------------------------*/
4094 createFunction (symbol * name, ast * body)
4100 iCode *piCode = NULL;
4102 /* if check function return 0 then some problem */
4103 if (checkFunction (name) == 0)
4106 /* create a dummy block if none exists */
4108 body = newNode (BLOCK, NULL, NULL);
4112 /* check if the function name already in the symbol table */
4113 if ((csym = findSym (SymbolTab, NULL, name->name)))
4116 /* special case for compiler defined functions
4117 we need to add the name to the publics list : this
4118 actually means we are now compiling the compiler
4122 addSet (&publics, name);
4128 allocVariables (name);
4130 name->lastLine = yylineno;
4132 processFuncArgs (currFunc, 0);
4134 /* set the stack pointer */
4135 /* PENDING: check this for the mcs51 */
4136 stackPtr = -port->stack.direction * port->stack.call_overhead;
4137 if (IS_ISR (name->etype))
4138 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4139 if (IS_RENT (name->etype) || options.stackAuto)
4140 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4142 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4144 fetype = getSpec (name->type); /* get the specifier for the function */
4145 /* if this is a reentrant function then */
4146 if (IS_RENT (fetype))
4149 allocParms (name->args); /* allocate the parameters */
4151 /* do processing for parameters that are passed in registers */
4152 processRegParms (name->args, body);
4154 /* set the stack pointer */
4158 /* allocate & autoinit the block variables */
4159 processBlockVars (body, &stack, ALLOCATE);
4161 /* save the stack information */
4162 if (options.useXstack)
4163 name->xstack = SPEC_STAK (fetype) = stack;
4165 name->stack = SPEC_STAK (fetype) = stack;
4167 /* name needs to be mangled */
4168 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4170 body = resolveSymbols (body); /* resolve the symbols */
4171 body = decorateType (body); /* propagateType & do semantic checks */
4173 ex = newAst_VALUE (symbolVal (name)); /* create name */
4174 ex = newNode (FUNCTION, ex, body);
4175 ex->values.args = name->args;
4179 werror (E_FUNC_NO_CODE, name->name);
4183 /* create the node & generate intermediate code */
4185 codeOutFile = code->oFile;
4186 piCode = iCodeFromAst (ex);
4190 werror (E_FUNC_NO_CODE, name->name);
4194 eBBlockFromiCode (piCode);
4196 /* if there are any statics then do them */
4199 GcurMemmap = statsg;
4200 codeOutFile = statsg->oFile;
4201 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4207 /* dealloc the block variables */
4208 processBlockVars (body, &stack, DEALLOCATE);
4209 /* deallocate paramaters */
4210 deallocParms (name->args);
4212 if (IS_RENT (fetype))
4215 /* we are done freeup memory & cleanup */
4220 addSet (&operKeyReset, name);
4221 applyToSet (operKeyReset, resetParmKey);
4224 cdbStructBlock (1, cdbFile);
4226 cleanUpLevel (LabelTab, 0);
4227 cleanUpBlock (StructTab, 1);
4228 cleanUpBlock (TypedefTab, 1);
4230 xstack->syms = NULL;
4231 istack->syms = NULL;
4236 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4237 /*-----------------------------------------------------------------*/
4238 /* ast_print : prints the ast (for debugging purposes) */
4239 /*-----------------------------------------------------------------*/
4241 void ast_print (ast * tree, FILE *outfile, int indent)
4246 /* can print only decorated trees */
4247 if (!tree->decorated) return;
4249 /* if any child is an error | this one is an error do nothing */
4250 if (tree->isError ||
4251 (tree->left && tree->left->isError) ||
4252 (tree->right && tree->right->isError)) {
4253 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4257 /* print the line */
4258 /* if not block & function */
4259 if (tree->type == EX_OP &&
4260 (tree->opval.op != FUNCTION &&
4261 tree->opval.op != BLOCK &&
4262 tree->opval.op != NULLOP)) {
4265 if (tree->opval.op == FUNCTION) {
4266 fprintf(outfile,"FUNCTION (%p) type (",tree);
4267 printTypeChain (tree->ftype,outfile);
4268 fprintf(outfile,")\n");
4269 ast_print(tree->left,outfile,indent+4);
4270 ast_print(tree->right,outfile,indent+4);
4273 if (tree->opval.op == BLOCK) {
4274 symbol *decls = tree->values.sym;
4275 fprintf(outfile,"{\n");
4277 INDENT(indent+4,outfile);
4278 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4279 printTypeChain(decls->type,outfile);
4280 fprintf(outfile,")\n");
4282 decls = decls->next;
4284 ast_print(tree->right,outfile,indent+4);
4285 fprintf(outfile,"}\n");
4288 if (tree->opval.op == NULLOP) {
4289 fprintf(outfile,"\n");
4290 ast_print(tree->left,outfile,indent);
4291 fprintf(outfile,"\n");
4292 ast_print(tree->right,outfile,indent);
4295 INDENT(indent,outfile);
4297 /*------------------------------------------------------------------*/
4298 /*----------------------------*/
4299 /* leaf has been reached */
4300 /*----------------------------*/
4301 /* if this is of type value */
4302 /* just get the type */
4303 if (tree->type == EX_VALUE) {
4305 if (IS_LITERAL (tree->opval.val->etype)) {
4306 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4307 (int) floatFromVal(tree->opval.val),
4308 (int) floatFromVal(tree->opval.val),
4309 floatFromVal(tree->opval.val));
4310 } else if (tree->opval.val->sym) {
4311 /* if the undefined flag is set then give error message */
4312 if (tree->opval.val->sym->undefined) {
4313 fprintf(outfile,"UNDEFINED SYMBOL ");
4315 fprintf(outfile,"SYMBOL ");
4317 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4320 fprintf(outfile," type (");
4321 printTypeChain(tree->ftype,outfile);
4322 fprintf(outfile,")\n");
4324 fprintf(outfile,"\n");
4329 /* if type link for the case of cast */
4330 if (tree->type == EX_LINK) {
4331 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4332 printTypeChain(tree->opval.lnk,outfile);
4333 fprintf(outfile,")\n");
4338 /* depending on type of operator do */
4340 switch (tree->opval.op) {
4341 /*------------------------------------------------------------------*/
4342 /*----------------------------*/
4344 /*----------------------------*/
4346 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4347 printTypeChain(tree->ftype,outfile);
4348 fprintf(outfile,")\n");
4349 ast_print(tree->left,outfile,indent+4);
4350 ast_print(tree->right,outfile,indent+4);
4353 /*------------------------------------------------------------------*/
4354 /*----------------------------*/
4356 /*----------------------------*/
4358 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4359 printTypeChain(tree->ftype,outfile);
4360 fprintf(outfile,")\n");
4361 ast_print(tree->left,outfile,indent+4);
4362 ast_print(tree->right,outfile,indent+4);
4365 /*------------------------------------------------------------------*/
4366 /*----------------------------*/
4367 /* struct/union pointer */
4368 /*----------------------------*/
4370 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4371 printTypeChain(tree->ftype,outfile);
4372 fprintf(outfile,")\n");
4373 ast_print(tree->left,outfile,indent+4);
4374 ast_print(tree->right,outfile,indent+4);
4377 /*------------------------------------------------------------------*/
4378 /*----------------------------*/
4379 /* ++/-- operation */
4380 /*----------------------------*/
4381 case INC_OP: /* incerement operator unary so left only */
4382 fprintf(outfile,"INC_OP (%p) type (",tree);
4383 printTypeChain(tree->ftype,outfile);
4384 fprintf(outfile,")\n");
4385 ast_print(tree->left,outfile,indent+4);
4389 fprintf(outfile,"DEC_OP (%p) type (",tree);
4390 printTypeChain(tree->ftype,outfile);
4391 fprintf(outfile,")\n");
4392 ast_print(tree->left,outfile,indent+4);
4395 /*------------------------------------------------------------------*/
4396 /*----------------------------*/
4398 /*----------------------------*/
4401 fprintf(outfile,"& (%p) type (",tree);
4402 printTypeChain(tree->ftype,outfile);
4403 fprintf(outfile,")\n");
4404 ast_print(tree->left,outfile,indent+4);
4405 ast_print(tree->right,outfile,indent+4);
4407 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4408 printTypeChain(tree->ftype,outfile);
4409 fprintf(outfile,")\n");
4410 ast_print(tree->left,outfile,indent+4);
4411 ast_print(tree->right,outfile,indent+4);
4414 /*----------------------------*/
4416 /*----------------------------*/
4418 fprintf(outfile,"OR (%p) type (",tree);
4419 printTypeChain(tree->ftype,outfile);
4420 fprintf(outfile,")\n");
4421 ast_print(tree->left,outfile,indent+4);
4422 ast_print(tree->right,outfile,indent+4);
4424 /*------------------------------------------------------------------*/
4425 /*----------------------------*/
4427 /*----------------------------*/
4429 fprintf(outfile,"XOR (%p) type (",tree);
4430 printTypeChain(tree->ftype,outfile);
4431 fprintf(outfile,")\n");
4432 ast_print(tree->left,outfile,indent+4);
4433 ast_print(tree->right,outfile,indent+4);
4436 /*------------------------------------------------------------------*/
4437 /*----------------------------*/
4439 /*----------------------------*/
4441 fprintf(outfile,"DIV (%p) type (",tree);
4442 printTypeChain(tree->ftype,outfile);
4443 fprintf(outfile,")\n");
4444 ast_print(tree->left,outfile,indent+4);
4445 ast_print(tree->right,outfile,indent+4);
4447 /*------------------------------------------------------------------*/
4448 /*----------------------------*/
4450 /*----------------------------*/
4452 fprintf(outfile,"MOD (%p) type (",tree);
4453 printTypeChain(tree->ftype,outfile);
4454 fprintf(outfile,")\n");
4455 ast_print(tree->left,outfile,indent+4);
4456 ast_print(tree->right,outfile,indent+4);
4459 /*------------------------------------------------------------------*/
4460 /*----------------------------*/
4461 /* address dereference */
4462 /*----------------------------*/
4463 case '*': /* can be unary : if right is null then unary operation */
4465 fprintf(outfile,"DEREF (%p) type (",tree);
4466 printTypeChain(tree->ftype,outfile);
4467 fprintf(outfile,")\n");
4468 ast_print(tree->left,outfile,indent+4);
4471 /*------------------------------------------------------------------*/
4472 /*----------------------------*/
4473 /* multiplication */
4474 /*----------------------------*/
4475 fprintf(outfile,"MULT (%p) type (",tree);
4476 printTypeChain(tree->ftype,outfile);
4477 fprintf(outfile,")\n");
4478 ast_print(tree->left,outfile,indent+4);
4479 ast_print(tree->right,outfile,indent+4);
4483 /*------------------------------------------------------------------*/
4484 /*----------------------------*/
4485 /* unary '+' operator */
4486 /*----------------------------*/
4490 fprintf(outfile,"UPLUS (%p) type (",tree);
4491 printTypeChain(tree->ftype,outfile);
4492 fprintf(outfile,")\n");
4493 ast_print(tree->left,outfile,indent+4);
4495 /*------------------------------------------------------------------*/
4496 /*----------------------------*/
4498 /*----------------------------*/
4499 fprintf(outfile,"ADD (%p) type (",tree);
4500 printTypeChain(tree->ftype,outfile);
4501 fprintf(outfile,")\n");
4502 ast_print(tree->left,outfile,indent+4);
4503 ast_print(tree->right,outfile,indent+4);
4506 /*------------------------------------------------------------------*/
4507 /*----------------------------*/
4509 /*----------------------------*/
4510 case '-': /* can be unary */
4512 fprintf(outfile,"UMINUS (%p) type (",tree);
4513 printTypeChain(tree->ftype,outfile);
4514 fprintf(outfile,")\n");
4515 ast_print(tree->left,outfile,indent+4);
4517 /*------------------------------------------------------------------*/
4518 /*----------------------------*/
4520 /*----------------------------*/
4521 fprintf(outfile,"SUB (%p) type (",tree);
4522 printTypeChain(tree->ftype,outfile);
4523 fprintf(outfile,")\n");
4524 ast_print(tree->left,outfile,indent+4);
4525 ast_print(tree->right,outfile,indent+4);
4528 /*------------------------------------------------------------------*/
4529 /*----------------------------*/
4531 /*----------------------------*/
4533 fprintf(outfile,"COMPL (%p) type (",tree);
4534 printTypeChain(tree->ftype,outfile);
4535 fprintf(outfile,")\n");
4536 ast_print(tree->left,outfile,indent+4);
4538 /*------------------------------------------------------------------*/
4539 /*----------------------------*/
4541 /*----------------------------*/
4543 fprintf(outfile,"NOT (%p) type (",tree);
4544 printTypeChain(tree->ftype,outfile);
4545 fprintf(outfile,")\n");
4546 ast_print(tree->left,outfile,indent+4);
4548 /*------------------------------------------------------------------*/
4549 /*----------------------------*/
4551 /*----------------------------*/
4553 fprintf(outfile,"RRC (%p) type (",tree);
4554 printTypeChain(tree->ftype,outfile);
4555 fprintf(outfile,")\n");
4556 ast_print(tree->left,outfile,indent+4);
4560 fprintf(outfile,"RLC (%p) type (",tree);
4561 printTypeChain(tree->ftype,outfile);
4562 fprintf(outfile,")\n");
4563 ast_print(tree->left,outfile,indent+4);
4566 fprintf(outfile,"GETHBIT (%p) type (",tree);
4567 printTypeChain(tree->ftype,outfile);
4568 fprintf(outfile,")\n");
4569 ast_print(tree->left,outfile,indent+4);
4572 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4573 printTypeChain(tree->ftype,outfile);
4574 fprintf(outfile,")\n");
4575 ast_print(tree->left,outfile,indent+4);
4576 ast_print(tree->right,outfile,indent+4);
4579 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4580 printTypeChain(tree->ftype,outfile);
4581 fprintf(outfile,")\n");
4582 ast_print(tree->left,outfile,indent+4);
4583 ast_print(tree->right,outfile,indent+4);
4585 /*------------------------------------------------------------------*/
4586 /*----------------------------*/
4588 /*----------------------------*/
4589 case CAST: /* change the type */
4590 fprintf(outfile,"CAST (%p) type (",tree);
4591 printTypeChain(tree->ftype,outfile);
4592 fprintf(outfile,")\n");
4593 ast_print(tree->right,outfile,indent+4);
4597 fprintf(outfile,"ANDAND (%p) type (",tree);
4598 printTypeChain(tree->ftype,outfile);
4599 fprintf(outfile,")\n");
4600 ast_print(tree->left,outfile,indent+4);
4601 ast_print(tree->right,outfile,indent+4);
4604 fprintf(outfile,"OROR (%p) type (",tree);
4605 printTypeChain(tree->ftype,outfile);
4606 fprintf(outfile,")\n");
4607 ast_print(tree->left,outfile,indent+4);
4608 ast_print(tree->right,outfile,indent+4);
4611 /*------------------------------------------------------------------*/
4612 /*----------------------------*/
4613 /* comparison operators */
4614 /*----------------------------*/
4616 fprintf(outfile,"GT(>) (%p) type (",tree);
4617 printTypeChain(tree->ftype,outfile);
4618 fprintf(outfile,")\n");
4619 ast_print(tree->left,outfile,indent+4);
4620 ast_print(tree->right,outfile,indent+4);
4623 fprintf(outfile,"LT(<) (%p) type (",tree);
4624 printTypeChain(tree->ftype,outfile);
4625 fprintf(outfile,")\n");
4626 ast_print(tree->left,outfile,indent+4);
4627 ast_print(tree->right,outfile,indent+4);
4630 fprintf(outfile,"LE(<=) (%p) type (",tree);
4631 printTypeChain(tree->ftype,outfile);
4632 fprintf(outfile,")\n");
4633 ast_print(tree->left,outfile,indent+4);
4634 ast_print(tree->right,outfile,indent+4);
4637 fprintf(outfile,"GE(>=) (%p) type (",tree);
4638 printTypeChain(tree->ftype,outfile);
4639 fprintf(outfile,")\n");
4640 ast_print(tree->left,outfile,indent+4);
4641 ast_print(tree->right,outfile,indent+4);
4644 fprintf(outfile,"EQ(==) (%p) type (",tree);
4645 printTypeChain(tree->ftype,outfile);
4646 fprintf(outfile,")\n");
4647 ast_print(tree->left,outfile,indent+4);
4648 ast_print(tree->right,outfile,indent+4);
4651 fprintf(outfile,"NE(!=) (%p) type (",tree);
4652 printTypeChain(tree->ftype,outfile);
4653 fprintf(outfile,")\n");
4654 ast_print(tree->left,outfile,indent+4);
4655 ast_print(tree->right,outfile,indent+4);
4656 /*------------------------------------------------------------------*/
4657 /*----------------------------*/
4659 /*----------------------------*/
4660 case SIZEOF: /* evaluate wihout code generation */
4661 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4664 /*------------------------------------------------------------------*/
4665 /*----------------------------*/
4666 /* conditional operator '?' */
4667 /*----------------------------*/
4669 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4670 printTypeChain(tree->ftype,outfile);
4671 fprintf(outfile,")\n");
4672 ast_print(tree->left,outfile,indent+4);
4673 ast_print(tree->right,outfile,indent+4);
4676 fprintf(outfile,"COLON(:) (%p) type (",tree);
4677 printTypeChain(tree->ftype,outfile);
4678 fprintf(outfile,")\n");
4679 ast_print(tree->left,outfile,indent+4);
4680 ast_print(tree->right,outfile,indent+4);
4683 /*------------------------------------------------------------------*/
4684 /*----------------------------*/
4685 /* assignment operators */
4686 /*----------------------------*/
4688 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4689 printTypeChain(tree->ftype,outfile);
4690 fprintf(outfile,")\n");
4691 ast_print(tree->left,outfile,indent+4);
4692 ast_print(tree->right,outfile,indent+4);
4695 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4696 printTypeChain(tree->ftype,outfile);
4697 fprintf(outfile,")\n");
4698 ast_print(tree->left,outfile,indent+4);
4699 ast_print(tree->right,outfile,indent+4);
4702 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4703 printTypeChain(tree->ftype,outfile);
4704 fprintf(outfile,")\n");
4705 ast_print(tree->left,outfile,indent+4);
4706 ast_print(tree->right,outfile,indent+4);
4709 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4710 printTypeChain(tree->ftype,outfile);
4711 fprintf(outfile,")\n");
4712 ast_print(tree->left,outfile,indent+4);
4713 ast_print(tree->right,outfile,indent+4);
4716 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4717 printTypeChain(tree->ftype,outfile);
4718 fprintf(outfile,")\n");
4719 ast_print(tree->left,outfile,indent+4);
4720 ast_print(tree->right,outfile,indent+4);
4723 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4724 printTypeChain(tree->ftype,outfile);
4725 fprintf(outfile,")\n");
4726 ast_print(tree->left,outfile,indent+4);
4727 ast_print(tree->right,outfile,indent+4);
4730 fprintf(outfile,"LSHFTASS(*=) (%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);
4736 /*------------------------------------------------------------------*/
4737 /*----------------------------*/
4739 /*----------------------------*/
4741 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4742 printTypeChain(tree->ftype,outfile);
4743 fprintf(outfile,")\n");
4744 ast_print(tree->left,outfile,indent+4);
4745 ast_print(tree->right,outfile,indent+4);
4747 /*------------------------------------------------------------------*/
4748 /*----------------------------*/
4750 /*----------------------------*/
4752 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4753 printTypeChain(tree->ftype,outfile);
4754 fprintf(outfile,")\n");
4755 ast_print(tree->left,outfile,indent+4);
4756 ast_print(tree->right,outfile,indent+4);
4758 /*------------------------------------------------------------------*/
4759 /*----------------------------*/
4760 /* straight assignemnt */
4761 /*----------------------------*/
4763 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+4);
4767 ast_print(tree->right,outfile,indent+4);
4769 /*------------------------------------------------------------------*/
4770 /*----------------------------*/
4771 /* comma operator */
4772 /*----------------------------*/
4774 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4775 printTypeChain(tree->ftype,outfile);
4776 fprintf(outfile,")\n");
4777 ast_print(tree->left,outfile,indent+4);
4778 ast_print(tree->right,outfile,indent+4);
4780 /*------------------------------------------------------------------*/
4781 /*----------------------------*/
4783 /*----------------------------*/
4786 fprintf(outfile,"CALL (%p) type (",tree);
4787 printTypeChain(tree->ftype,outfile);
4788 fprintf(outfile,")\n");
4789 ast_print(tree->left,outfile,indent+4);
4790 ast_print(tree->right,outfile,indent+4);
4793 fprintf(outfile,"PARM ");
4794 ast_print(tree->left,outfile,indent+4);
4795 if (tree->right && !IS_AST_PARAM(tree->right)) {
4796 fprintf(outfile,"PARM ");
4797 ast_print(tree->right,outfile,indent+4);
4800 /*------------------------------------------------------------------*/
4801 /*----------------------------*/
4802 /* return statement */
4803 /*----------------------------*/
4805 fprintf(outfile,"RETURN (%p) type (",tree);
4806 printTypeChain(tree->right->ftype,outfile);
4807 fprintf(outfile,")\n");
4808 ast_print(tree->right,outfile,indent+4);
4810 /*------------------------------------------------------------------*/
4811 /*----------------------------*/
4812 /* label statement */
4813 /*----------------------------*/
4815 fprintf(outfile,"LABEL (%p)",tree);
4816 ast_print(tree->left,outfile,indent+4);
4817 ast_print(tree->right,outfile,indent);
4819 /*------------------------------------------------------------------*/
4820 /*----------------------------*/
4821 /* switch statement */
4822 /*----------------------------*/
4826 fprintf(outfile,"SWITCH (%p) ",tree);
4827 ast_print(tree->left,outfile,0);
4828 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4829 INDENT(indent+4,outfile);
4830 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4831 (int) floatFromVal(val),
4832 tree->values.switchVals.swNum,
4833 (int) floatFromVal(val));
4835 ast_print(tree->right,outfile,indent);
4838 /*------------------------------------------------------------------*/
4839 /*----------------------------*/
4841 /*----------------------------*/
4843 ast_print(tree->left,outfile,indent);
4844 INDENT(indent,outfile);
4845 fprintf(outfile,"IF (%p) \n",tree);
4846 if (tree->trueLabel) {
4847 INDENT(indent,outfile);
4848 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4850 if (tree->falseLabel) {
4851 INDENT(indent,outfile);
4852 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4854 ast_print(tree->right,outfile,indent);
4856 /*------------------------------------------------------------------*/
4857 /*----------------------------*/
4859 /*----------------------------*/
4861 fprintf(outfile,"FOR (%p) \n",tree);
4862 if (AST_FOR( tree, initExpr)) {
4863 INDENT(indent+4,outfile);
4864 fprintf(outfile,"INIT EXPR ");
4865 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4867 if (AST_FOR( tree, condExpr)) {
4868 INDENT(indent+4,outfile);
4869 fprintf(outfile,"COND EXPR ");
4870 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4872 if (AST_FOR( tree, loopExpr)) {
4873 INDENT(indent+4,outfile);
4874 fprintf(outfile,"LOOP EXPR ");
4875 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4877 fprintf(outfile,"FOR LOOP BODY \n");
4878 ast_print(tree->left,outfile,indent+4);
4887 ast_print(t,stdout,1);