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);
1027 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1029 return decorateType (resolveSymbols (rast));
1032 /*-----------------------------------------------------------------*/
1033 /* initAggregates - initialises aggregate variables with initv */
1034 /*-----------------------------------------------------------------*/
1036 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1038 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1042 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1044 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1045 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1046 "with -mmcs51 and --model-large");
1050 if (SPEC_OCLS(sym->etype)==xdata &&
1051 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1054 newSym=copySymbol (sym);
1055 SPEC_OCLS(newSym->etype)=code;
1056 sprintf (newSym->name, "%s_init__", sym->name);
1057 sprintf (newSym->rname,"%s_init__", sym->rname);
1058 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1060 // emit it in the static segment
1061 addSet(&statsg->syms, newSym);
1063 // now memcpy() the entire array from cseg
1064 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1065 newAst_VALUE (symbolVal (sym)),
1066 newAst_VALUE (symbolVal (newSym)));
1067 return decorateType(resolveSymbols(ast));
1071 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1074 /*-----------------------------------------------------------------*/
1075 /* gatherAutoInit - creates assignment expressions for initial */
1077 /*-----------------------------------------------------------------*/
1079 gatherAutoInit (symbol * autoChain)
1086 for (sym = autoChain; sym; sym = sym->next)
1089 /* resolve the symbols in the ival */
1091 resolveIvalSym (sym->ival);
1093 /* if this is a static variable & has an */
1094 /* initial value the code needs to be lifted */
1095 /* here to the main portion since they can be */
1096 /* initialised only once at the start */
1097 if (IS_STATIC (sym->etype) && sym->ival &&
1098 SPEC_SCLS (sym->etype) != S_CODE)
1102 // this can only be a constant
1103 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1104 werror (E_CONST_EXPECTED);
1107 /* insert the symbol into the symbol table */
1108 /* with level = 0 & name = rname */
1109 newSym = copySymbol (sym);
1110 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1112 /* now lift the code to main */
1113 if (IS_AGGREGATE (sym->type))
1114 work = initAggregates (sym, sym->ival, NULL);
1116 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1117 list2expr (sym->ival));
1119 setAstLineno (work, sym->lineDef);
1123 staticAutos = newNode (NULLOP, staticAutos, work);
1130 /* if there is an initial value */
1131 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1133 if (IS_AGGREGATE (sym->type))
1134 work = initAggregates (sym, sym->ival, NULL);
1136 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1137 list2expr (sym->ival));
1139 setAstLineno (work, sym->lineDef);
1142 init = newNode (NULLOP, init, work);
1151 /*-----------------------------------------------------------------*/
1152 /* stringToSymbol - creates a symbol from a literal string */
1153 /*-----------------------------------------------------------------*/
1155 stringToSymbol (value * val)
1157 char name[SDCC_NAME_MAX + 1];
1158 static int charLbl = 0;
1161 sprintf (name, "_str_%d", charLbl++);
1162 sym = newSymbol (name, 0); /* make it @ level 0 */
1163 strcpy (sym->rname, name);
1165 /* copy the type from the value passed */
1166 sym->type = copyLinkChain (val->type);
1167 sym->etype = getSpec (sym->type);
1168 /* change to storage class & output class */
1169 SPEC_SCLS (sym->etype) = S_CODE;
1170 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1171 SPEC_STAT (sym->etype) = 1;
1172 /* make the level & block = 0 */
1173 sym->block = sym->level = 0;
1175 /* create an ival */
1176 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1181 allocVariables (sym);
1184 return symbolVal (sym);
1188 /*-----------------------------------------------------------------*/
1189 /* processBlockVars - will go thru the ast looking for block if */
1190 /* a block is found then will allocate the syms */
1191 /* will also gather the auto inits present */
1192 /*-----------------------------------------------------------------*/
1194 processBlockVars (ast * tree, int *stack, int action)
1199 /* if this is a block */
1200 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1204 if (action == ALLOCATE)
1206 *stack += allocVariables (tree->values.sym);
1207 autoInit = gatherAutoInit (tree->values.sym);
1209 /* if there are auto inits then do them */
1211 tree->left = newNode (NULLOP, autoInit, tree->left);
1213 else /* action is deallocate */
1214 deallocLocal (tree->values.sym);
1217 processBlockVars (tree->left, stack, action);
1218 processBlockVars (tree->right, stack, action);
1222 /*-----------------------------------------------------------------*/
1223 /* constExprValue - returns the value of a constant expression */
1224 /*-----------------------------------------------------------------*/
1226 constExprValue (ast * cexpr, int check)
1228 cexpr = decorateType (resolveSymbols (cexpr));
1230 /* if this is not a constant then */
1231 if (!IS_LITERAL (cexpr->ftype))
1233 /* then check if this is a literal array
1235 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1236 SPEC_CVAL (cexpr->etype).v_char &&
1237 IS_ARRAY (cexpr->ftype))
1239 value *val = valFromType (cexpr->ftype);
1240 SPEC_SCLS (val->etype) = S_LITERAL;
1241 val->sym = cexpr->opval.val->sym;
1242 val->sym->type = copyLinkChain (cexpr->ftype);
1243 val->sym->etype = getSpec (val->sym->type);
1244 strcpy (val->name, cexpr->opval.val->sym->rname);
1248 /* if we are casting a literal value then */
1249 if (IS_AST_OP (cexpr) &&
1250 cexpr->opval.op == CAST &&
1251 IS_LITERAL (cexpr->left->ftype))
1252 return valCastLiteral (cexpr->ftype,
1253 floatFromVal (cexpr->left->opval.val));
1255 if (IS_AST_VALUE (cexpr))
1256 return cexpr->opval.val;
1259 werror (E_CONST_EXPECTED, "found expression");
1264 /* return the value */
1265 return cexpr->opval.val;
1269 /*-----------------------------------------------------------------*/
1270 /* isLabelInAst - will return true if a given label is found */
1271 /*-----------------------------------------------------------------*/
1273 isLabelInAst (symbol * label, ast * tree)
1275 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1278 if (IS_AST_OP (tree) &&
1279 tree->opval.op == LABEL &&
1280 isSymbolEqual (AST_SYMBOL (tree->left), label))
1283 return isLabelInAst (label, tree->right) &&
1284 isLabelInAst (label, tree->left);
1288 /*-----------------------------------------------------------------*/
1289 /* isLoopCountable - return true if the loop count can be determi- */
1290 /* -ned at compile time . */
1291 /*-----------------------------------------------------------------*/
1293 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1294 symbol ** sym, ast ** init, ast ** end)
1297 /* the loop is considered countable if the following
1298 conditions are true :-
1300 a) initExpr :- <sym> = <const>
1301 b) condExpr :- <sym> < <const1>
1302 c) loopExpr :- <sym> ++
1305 /* first check the initExpr */
1306 if (IS_AST_OP (initExpr) &&
1307 initExpr->opval.op == '=' && /* is assignment */
1308 IS_AST_SYM_VALUE (initExpr->left))
1309 { /* left is a symbol */
1311 *sym = AST_SYMBOL (initExpr->left);
1312 *init = initExpr->right;
1317 /* for now the symbol has to be of
1319 if (!IS_INTEGRAL ((*sym)->type))
1322 /* now check condExpr */
1323 if (IS_AST_OP (condExpr))
1326 switch (condExpr->opval.op)
1329 if (IS_AST_SYM_VALUE (condExpr->left) &&
1330 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1331 IS_AST_LIT_VALUE (condExpr->right))
1333 *end = condExpr->right;
1339 if (IS_AST_OP (condExpr->left) &&
1340 condExpr->left->opval.op == '>' &&
1341 IS_AST_LIT_VALUE (condExpr->left->right) &&
1342 IS_AST_SYM_VALUE (condExpr->left->left) &&
1343 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1346 *end = newNode ('+', condExpr->left->right,
1347 newAst_VALUE (constVal ("1")));
1358 /* check loop expression is of the form <sym>++ */
1359 if (!IS_AST_OP (loopExpr))
1362 /* check if <sym> ++ */
1363 if (loopExpr->opval.op == INC_OP)
1369 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1370 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1377 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1378 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1386 if (loopExpr->opval.op == ADD_ASSIGN)
1389 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1390 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1391 IS_AST_LIT_VALUE (loopExpr->right) &&
1392 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1400 /*-----------------------------------------------------------------*/
1401 /* astHasVolatile - returns true if ast contains any volatile */
1402 /*-----------------------------------------------------------------*/
1404 astHasVolatile (ast * tree)
1409 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1412 if (IS_AST_OP (tree))
1413 return astHasVolatile (tree->left) ||
1414 astHasVolatile (tree->right);
1419 /*-----------------------------------------------------------------*/
1420 /* astHasPointer - return true if the ast contains any ptr variable */
1421 /*-----------------------------------------------------------------*/
1423 astHasPointer (ast * tree)
1428 if (IS_AST_LINK (tree))
1431 /* if we hit an array expression then check
1432 only the left side */
1433 if (IS_AST_OP (tree) && tree->opval.op == '[')
1434 return astHasPointer (tree->left);
1436 if (IS_AST_VALUE (tree))
1437 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1439 return astHasPointer (tree->left) ||
1440 astHasPointer (tree->right);
1444 /*-----------------------------------------------------------------*/
1445 /* astHasSymbol - return true if the ast has the given symbol */
1446 /*-----------------------------------------------------------------*/
1448 astHasSymbol (ast * tree, symbol * sym)
1450 if (!tree || IS_AST_LINK (tree))
1453 if (IS_AST_VALUE (tree))
1455 if (IS_AST_SYM_VALUE (tree))
1456 return isSymbolEqual (AST_SYMBOL (tree), sym);
1461 return astHasSymbol (tree->left, sym) ||
1462 astHasSymbol (tree->right, sym);
1465 /*-----------------------------------------------------------------*/
1466 /* astHasDeref - return true if the ast has an indirect access */
1467 /*-----------------------------------------------------------------*/
1469 astHasDeref (ast * tree)
1471 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1474 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1476 return astHasDeref (tree->left) || astHasDeref (tree->right);
1479 /*-----------------------------------------------------------------*/
1480 /* isConformingBody - the loop body has to conform to a set of rules */
1481 /* for the loop to be considered reversible read on for rules */
1482 /*-----------------------------------------------------------------*/
1484 isConformingBody (ast * pbody, symbol * sym, ast * body)
1487 /* we are going to do a pre-order traversal of the
1488 tree && check for the following conditions. (essentially
1489 a set of very shallow tests )
1490 a) the sym passed does not participate in
1491 any arithmetic operation
1492 b) There are no function calls
1493 c) all jumps are within the body
1494 d) address of loop control variable not taken
1495 e) if an assignment has a pointer on the
1496 left hand side make sure right does not have
1497 loop control variable */
1499 /* if we reach the end or a leaf then true */
1500 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1504 /* if anything else is "volatile" */
1505 if (IS_VOLATILE (TETYPE (pbody)))
1508 /* we will walk the body in a pre-order traversal for
1510 switch (pbody->opval.op)
1512 /*------------------------------------------------------------------*/
1514 return isConformingBody (pbody->right, sym, body);
1516 /*------------------------------------------------------------------*/
1521 /*------------------------------------------------------------------*/
1522 case INC_OP: /* incerement operator unary so left only */
1525 /* sure we are not sym is not modified */
1527 IS_AST_SYM_VALUE (pbody->left) &&
1528 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1532 IS_AST_SYM_VALUE (pbody->right) &&
1533 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1538 /*------------------------------------------------------------------*/
1540 case '*': /* can be unary : if right is null then unary operation */
1545 /* if right is NULL then unary operation */
1546 /*------------------------------------------------------------------*/
1547 /*----------------------------*/
1549 /*----------------------------*/
1552 if (IS_AST_SYM_VALUE (pbody->left) &&
1553 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1556 return isConformingBody (pbody->left, sym, body);
1560 if (astHasSymbol (pbody->left, sym) ||
1561 astHasSymbol (pbody->right, sym))
1566 /*------------------------------------------------------------------*/
1574 if (IS_AST_SYM_VALUE (pbody->left) &&
1575 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1578 if (IS_AST_SYM_VALUE (pbody->right) &&
1579 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1582 return isConformingBody (pbody->left, sym, body) &&
1583 isConformingBody (pbody->right, sym, body);
1590 if (IS_AST_SYM_VALUE (pbody->left) &&
1591 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1593 return isConformingBody (pbody->left, sym, body);
1595 /*------------------------------------------------------------------*/
1607 case SIZEOF: /* evaluate wihout code generation */
1609 return isConformingBody (pbody->left, sym, body) &&
1610 isConformingBody (pbody->right, sym, body);
1612 /*------------------------------------------------------------------*/
1615 /* if left has a pointer & right has loop
1616 control variable then we cannot */
1617 if (astHasPointer (pbody->left) &&
1618 astHasSymbol (pbody->right, sym))
1620 if (astHasVolatile (pbody->left))
1623 if (IS_AST_SYM_VALUE (pbody->left) &&
1624 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1627 if (astHasVolatile (pbody->left))
1630 if (astHasDeref(pbody->right)) return FALSE;
1632 return isConformingBody (pbody->left, sym, body) &&
1633 isConformingBody (pbody->right, sym, body);
1644 assert ("Parser should not have generated this\n");
1646 /*------------------------------------------------------------------*/
1647 /*----------------------------*/
1648 /* comma operator */
1649 /*----------------------------*/
1651 return isConformingBody (pbody->left, sym, body) &&
1652 isConformingBody (pbody->right, sym, body);
1654 /*------------------------------------------------------------------*/
1655 /*----------------------------*/
1657 /*----------------------------*/
1661 /*------------------------------------------------------------------*/
1662 /*----------------------------*/
1663 /* return statement */
1664 /*----------------------------*/
1669 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1674 if (astHasSymbol (pbody->left, sym))
1681 return isConformingBody (pbody->left, sym, body) &&
1682 isConformingBody (pbody->right, sym, body);
1688 /*-----------------------------------------------------------------*/
1689 /* isLoopReversible - takes a for loop as input && returns true */
1690 /* if the for loop is reversible. If yes will set the value of */
1691 /* the loop control var & init value & termination value */
1692 /*-----------------------------------------------------------------*/
1694 isLoopReversible (ast * loop, symbol ** loopCntrl,
1695 ast ** init, ast ** end)
1697 /* if option says don't do it then don't */
1698 if (optimize.noLoopReverse)
1700 /* there are several tests to determine this */
1702 /* for loop has to be of the form
1703 for ( <sym> = <const1> ;
1704 [<sym> < <const2>] ;
1705 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1707 if (!isLoopCountable (AST_FOR (loop, initExpr),
1708 AST_FOR (loop, condExpr),
1709 AST_FOR (loop, loopExpr),
1710 loopCntrl, init, end))
1713 /* now do some serious checking on the body of the loop
1716 return isConformingBody (loop->left, *loopCntrl, loop->left);
1720 /*-----------------------------------------------------------------*/
1721 /* replLoopSym - replace the loop sym by loop sym -1 */
1722 /*-----------------------------------------------------------------*/
1724 replLoopSym (ast * body, symbol * sym)
1727 if (!body || IS_AST_LINK (body))
1730 if (IS_AST_SYM_VALUE (body))
1733 if (isSymbolEqual (AST_SYMBOL (body), sym))
1737 body->opval.op = '-';
1738 body->left = newAst_VALUE (symbolVal (sym));
1739 body->right = newAst_VALUE (constVal ("1"));
1747 replLoopSym (body->left, sym);
1748 replLoopSym (body->right, sym);
1752 /*-----------------------------------------------------------------*/
1753 /* reverseLoop - do the actual loop reversal */
1754 /*-----------------------------------------------------------------*/
1756 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1760 /* create the following tree
1765 if (sym) goto for_continue ;
1768 /* put it together piece by piece */
1769 rloop = newNode (NULLOP,
1770 createIf (newAst_VALUE (symbolVal (sym)),
1772 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1775 newAst_VALUE (symbolVal (sym)),
1778 replLoopSym (loop->left, sym);
1780 rloop = newNode (NULLOP,
1782 newAst_VALUE (symbolVal (sym)),
1783 newNode ('-', end, init)),
1784 createLabel (AST_FOR (loop, continueLabel),
1788 newNode (SUB_ASSIGN,
1789 newAst_VALUE (symbolVal (sym)),
1790 newAst_VALUE (constVal ("1"))),
1793 return decorateType (rloop);
1797 //#define DEMAND_INTEGER_PROMOTION
1799 #ifdef DEMAND_INTEGER_PROMOTION
1801 /*-----------------------------------------------------------------*/
1802 /* walk a tree looking for the leaves. Add a typecast to the given */
1803 /* type to each value leaf node. */
1804 /*-----------------------------------------------------------------*/
1806 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1808 if (!node || IS_CALLOP(node))
1810 /* WTF? We should never get here. */
1814 if (!node->left && !node->right)
1816 /* We're at a leaf; if it's a value, apply the typecast */
1817 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1819 *parentPtr = decorateType (newNode (CAST,
1820 newAst_LINK (copyLinkChain (type)),
1828 pushTypeCastToLeaves (type, node->left, &(node->left));
1832 pushTypeCastToLeaves (type, node->right, &(node->right));
1839 /*-----------------------------------------------------------------*/
1840 /* Given an assignment operation in a tree, determine if the LHS */
1841 /* (the result) has a different (integer) type than the RHS. */
1842 /* If so, walk the RHS and add a typecast to the type of the LHS */
1843 /* to all leaf nodes. */
1844 /*-----------------------------------------------------------------*/
1846 propAsgType (ast * tree)
1848 #ifdef DEMAND_INTEGER_PROMOTION
1849 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1851 /* Nothing to do here... */
1855 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1857 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1864 /*-----------------------------------------------------------------*/
1865 /* decorateType - compute type for this tree also does type cheking */
1866 /* this is done bottom up, since type have to flow upwards */
1867 /* it also does constant folding, and paramater checking */
1868 /*-----------------------------------------------------------------*/
1870 decorateType (ast * tree)
1878 /* if already has type then do nothing */
1879 if (tree->decorated)
1882 tree->decorated = 1;
1884 /* print the line */
1885 /* if not block & function */
1886 if (tree->type == EX_OP &&
1887 (tree->opval.op != FUNCTION &&
1888 tree->opval.op != BLOCK &&
1889 tree->opval.op != NULLOP))
1891 filename = tree->filename;
1892 lineno = tree->lineno;
1895 /* if any child is an error | this one is an error do nothing */
1896 if (tree->isError ||
1897 (tree->left && tree->left->isError) ||
1898 (tree->right && tree->right->isError))
1901 /*------------------------------------------------------------------*/
1902 /*----------------------------*/
1903 /* leaf has been reached */
1904 /*----------------------------*/
1905 /* if this is of type value */
1906 /* just get the type */
1907 if (tree->type == EX_VALUE)
1910 if (IS_LITERAL (tree->opval.val->etype))
1913 /* if this is a character array then declare it */
1914 if (IS_ARRAY (tree->opval.val->type))
1915 tree->opval.val = stringToSymbol (tree->opval.val);
1917 /* otherwise just copy the type information */
1918 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1919 if (funcInChain (tree->opval.val->type))
1921 tree->hasVargs = tree->opval.val->sym->hasVargs;
1922 tree->args = copyValueChain (tree->opval.val->sym->args);
1927 if (tree->opval.val->sym)
1929 /* if the undefined flag is set then give error message */
1930 if (tree->opval.val->sym->undefined)
1932 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1934 TTYPE (tree) = TETYPE (tree) =
1935 tree->opval.val->type = tree->opval.val->sym->type =
1936 tree->opval.val->etype = tree->opval.val->sym->etype =
1937 copyLinkChain (INTTYPE);
1942 /* if impilicit i.e. struct/union member then no type */
1943 if (tree->opval.val->sym->implicit)
1944 TTYPE (tree) = TETYPE (tree) = NULL;
1949 /* else copy the type */
1950 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1952 /* and mark it as referenced */
1953 tree->opval.val->sym->isref = 1;
1954 /* if this is of type function or function pointer */
1955 if (funcInChain (tree->opval.val->type))
1957 tree->hasVargs = tree->opval.val->sym->hasVargs;
1958 tree->args = copyValueChain (tree->opval.val->sym->args);
1968 /* if type link for the case of cast */
1969 if (tree->type == EX_LINK)
1971 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1978 dtl = decorateType (tree->left);
1979 dtr = decorateType (tree->right);
1981 /* this is to take care of situations
1982 when the tree gets rewritten */
1983 if (dtl != tree->left)
1985 if (dtr != tree->right)
1989 /* depending on type of operator do */
1991 switch (tree->opval.op)
1993 /*------------------------------------------------------------------*/
1994 /*----------------------------*/
1996 /*----------------------------*/
1999 /* determine which is the array & which the index */
2000 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2003 ast *tempTree = tree->left;
2004 tree->left = tree->right;
2005 tree->right = tempTree;
2008 /* first check if this is a array or a pointer */
2009 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2011 werror (E_NEED_ARRAY_PTR, "[]");
2012 goto errorTreeReturn;
2015 /* check if the type of the idx */
2016 if (!IS_INTEGRAL (RTYPE (tree)))
2018 werror (E_IDX_NOT_INT);
2019 goto errorTreeReturn;
2022 /* if the left is an rvalue then error */
2025 werror (E_LVALUE_REQUIRED, "array access");
2026 goto errorTreeReturn;
2029 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2030 if (IS_PTR(LTYPE(tree))) {
2031 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2035 /*------------------------------------------------------------------*/
2036 /*----------------------------*/
2038 /*----------------------------*/
2040 /* if this is not a structure */
2041 if (!IS_STRUCT (LTYPE (tree)))
2043 werror (E_STRUCT_UNION, ".");
2044 goto errorTreeReturn;
2046 TTYPE (tree) = structElemType (LTYPE (tree),
2047 (tree->right->type == EX_VALUE ?
2048 tree->right->opval.val : NULL), &tree->args);
2049 TETYPE (tree) = getSpec (TTYPE (tree));
2052 /*------------------------------------------------------------------*/
2053 /*----------------------------*/
2054 /* struct/union pointer */
2055 /*----------------------------*/
2057 /* if not pointer to a structure */
2058 if (!IS_PTR (LTYPE (tree)))
2060 werror (E_PTR_REQD);
2061 goto errorTreeReturn;
2064 if (!IS_STRUCT (LTYPE (tree)->next))
2066 werror (E_STRUCT_UNION, "->");
2067 goto errorTreeReturn;
2070 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2071 (tree->right->type == EX_VALUE ?
2072 tree->right->opval.val : NULL), &tree->args);
2073 TETYPE (tree) = getSpec (TTYPE (tree));
2076 /*------------------------------------------------------------------*/
2077 /*----------------------------*/
2078 /* ++/-- operation */
2079 /*----------------------------*/
2080 case INC_OP: /* incerement operator unary so left only */
2083 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2084 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2085 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
2086 werror (E_CODE_WRITE, "++/--");
2095 /*------------------------------------------------------------------*/
2096 /*----------------------------*/
2098 /*----------------------------*/
2099 case '&': /* can be unary */
2100 /* if right is NULL then unary operation */
2101 if (tree->right) /* not an unary operation */
2104 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2106 werror (E_BITWISE_OP);
2107 werror (E_CONTINUE, "left & right types are ");
2108 printTypeChain (LTYPE (tree), stderr);
2109 fprintf (stderr, ",");
2110 printTypeChain (RTYPE (tree), stderr);
2111 fprintf (stderr, "\n");
2112 goto errorTreeReturn;
2115 /* if they are both literal */
2116 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2118 tree->type = EX_VALUE;
2119 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2120 valFromType (RETYPE (tree)), '&');
2122 tree->right = tree->left = NULL;
2123 TETYPE (tree) = tree->opval.val->etype;
2124 TTYPE (tree) = tree->opval.val->type;
2128 /* see if this is a GETHBIT operation if yes
2131 ast *otree = optimizeGetHbit (tree);
2134 return decorateType (otree);
2138 // we can't do this because of "(int & 0xff) << 3"
2140 /* if right or left is literal then result of that type */
2141 if (IS_LITERAL (RTYPE (tree)))
2144 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2145 TETYPE (tree) = getSpec (TTYPE (tree));
2146 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2150 if (IS_LITERAL (LTYPE (tree)))
2152 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2153 TETYPE (tree) = getSpec (TTYPE (tree));
2154 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2160 computeType (LTYPE (tree), RTYPE (tree));
2161 TETYPE (tree) = getSpec (TTYPE (tree));
2166 computeType (LTYPE (tree), RTYPE (tree));
2167 TETYPE (tree) = getSpec (TTYPE (tree));
2169 LRVAL (tree) = RRVAL (tree) = 1;
2173 /*------------------------------------------------------------------*/
2174 /*----------------------------*/
2176 /*----------------------------*/
2178 p->class = DECLARATOR;
2179 /* if bit field then error */
2180 if (IS_BITVAR (tree->left->etype))
2182 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2183 goto errorTreeReturn;
2186 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2188 werror (E_ILLEGAL_ADDR, "address of register variable");
2189 goto errorTreeReturn;
2192 if (IS_FUNC (LTYPE (tree)))
2194 werror (E_ILLEGAL_ADDR, "address of function");
2195 goto errorTreeReturn;
2200 werror (E_LVALUE_REQUIRED, "address of");
2201 goto errorTreeReturn;
2203 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2205 DCL_TYPE (p) = CPOINTER;
2206 DCL_PTR_CONST (p) = port->mem.code_ro;
2208 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2209 DCL_TYPE (p) = FPOINTER;
2210 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2211 DCL_TYPE (p) = PPOINTER;
2212 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2213 DCL_TYPE (p) = IPOINTER;
2214 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2215 DCL_TYPE (p) = EEPPOINTER;
2217 DCL_TYPE (p) = POINTER;
2219 if (IS_AST_SYM_VALUE (tree->left))
2221 AST_SYMBOL (tree->left)->addrtaken = 1;
2222 AST_SYMBOL (tree->left)->allocreq = 1;
2225 p->next = LTYPE (tree);
2227 TETYPE (tree) = getSpec (TTYPE (tree));
2228 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2229 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2234 /*------------------------------------------------------------------*/
2235 /*----------------------------*/
2237 /*----------------------------*/
2239 /* if the rewrite succeeds then don't go any furthur */
2241 ast *wtree = optimizeRRCRLC (tree);
2243 return decorateType (wtree);
2245 /*------------------------------------------------------------------*/
2246 /*----------------------------*/
2248 /*----------------------------*/
2250 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2252 werror (E_BITWISE_OP);
2253 werror (E_CONTINUE, "left & right types are ");
2254 printTypeChain (LTYPE (tree), stderr);
2255 fprintf (stderr, ",");
2256 printTypeChain (RTYPE (tree), stderr);
2257 fprintf (stderr, "\n");
2258 goto errorTreeReturn;
2261 /* if they are both literal then */
2262 /* rewrite the tree */
2263 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2265 tree->type = EX_VALUE;
2266 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2267 valFromType (RETYPE (tree)),
2269 tree->right = tree->left = NULL;
2270 TETYPE (tree) = tree->opval.val->etype;
2271 TTYPE (tree) = tree->opval.val->type;
2274 LRVAL (tree) = RRVAL (tree) = 1;
2275 TETYPE (tree) = getSpec (TTYPE (tree) =
2276 computeType (LTYPE (tree),
2279 /*------------------------------------------------------------------*/
2280 /*----------------------------*/
2282 /*----------------------------*/
2284 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2286 werror (E_INVALID_OP, "divide");
2287 goto errorTreeReturn;
2289 /* if they are both literal then */
2290 /* rewrite the tree */
2291 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2293 tree->type = EX_VALUE;
2294 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2295 valFromType (RETYPE (tree)));
2296 tree->right = tree->left = NULL;
2297 TETYPE (tree) = getSpec (TTYPE (tree) =
2298 tree->opval.val->type);
2301 LRVAL (tree) = RRVAL (tree) = 1;
2302 TETYPE (tree) = getSpec (TTYPE (tree) =
2303 computeType (LTYPE (tree),
2307 /*------------------------------------------------------------------*/
2308 /*----------------------------*/
2310 /*----------------------------*/
2312 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2314 werror (E_BITWISE_OP);
2315 werror (E_CONTINUE, "left & right types are ");
2316 printTypeChain (LTYPE (tree), stderr);
2317 fprintf (stderr, ",");
2318 printTypeChain (RTYPE (tree), stderr);
2319 fprintf (stderr, "\n");
2320 goto errorTreeReturn;
2322 /* if they are both literal then */
2323 /* rewrite the tree */
2324 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2326 tree->type = EX_VALUE;
2327 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2328 valFromType (RETYPE (tree)));
2329 tree->right = tree->left = NULL;
2330 TETYPE (tree) = getSpec (TTYPE (tree) =
2331 tree->opval.val->type);
2334 LRVAL (tree) = RRVAL (tree) = 1;
2335 TETYPE (tree) = getSpec (TTYPE (tree) =
2336 computeType (LTYPE (tree),
2340 /*------------------------------------------------------------------*/
2341 /*----------------------------*/
2342 /* address dereference */
2343 /*----------------------------*/
2344 case '*': /* can be unary : if right is null then unary operation */
2347 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2349 werror (E_PTR_REQD);
2350 goto errorTreeReturn;
2355 werror (E_LVALUE_REQUIRED, "pointer deref");
2356 goto errorTreeReturn;
2358 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2359 LTYPE (tree)->next : NULL);
2360 TETYPE (tree) = getSpec (TTYPE (tree));
2361 tree->args = tree->left->args;
2362 tree->hasVargs = tree->left->hasVargs;
2363 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2367 /*------------------------------------------------------------------*/
2368 /*----------------------------*/
2369 /* multiplication */
2370 /*----------------------------*/
2371 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2373 werror (E_INVALID_OP, "multiplication");
2374 goto errorTreeReturn;
2377 /* if they are both literal then */
2378 /* rewrite the tree */
2379 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2381 tree->type = EX_VALUE;
2382 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2383 valFromType (RETYPE (tree)));
2384 tree->right = tree->left = NULL;
2385 TETYPE (tree) = getSpec (TTYPE (tree) =
2386 tree->opval.val->type);
2390 /* if left is a literal exchange left & right */
2391 if (IS_LITERAL (LTYPE (tree)))
2393 ast *tTree = tree->left;
2394 tree->left = tree->right;
2395 tree->right = tTree;
2398 LRVAL (tree) = RRVAL (tree) = 1;
2399 /* promote result to int if left & right are char
2400 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2401 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2402 TETYPE (tree) = getSpec (TTYPE (tree) =
2403 computeType (LTYPE (tree),
2405 SPEC_NOUN(TETYPE(tree)) = V_INT;
2407 TETYPE (tree) = getSpec (TTYPE (tree) =
2408 computeType (LTYPE (tree),
2413 /*------------------------------------------------------------------*/
2414 /*----------------------------*/
2415 /* unary '+' operator */
2416 /*----------------------------*/
2421 if (!IS_INTEGRAL (LTYPE (tree)))
2423 werror (E_UNARY_OP, '+');
2424 goto errorTreeReturn;
2427 /* if left is a literal then do it */
2428 if (IS_LITERAL (LTYPE (tree)))
2430 tree->type = EX_VALUE;
2431 tree->opval.val = valFromType (LETYPE (tree));
2433 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2437 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2441 /*------------------------------------------------------------------*/
2442 /*----------------------------*/
2444 /*----------------------------*/
2446 /* this is not a unary operation */
2447 /* if both pointers then problem */
2448 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2449 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2451 werror (E_PTR_PLUS_PTR);
2452 goto errorTreeReturn;
2455 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2456 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2458 werror (E_PLUS_INVALID, "+");
2459 goto errorTreeReturn;
2462 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2463 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2465 werror (E_PLUS_INVALID, "+");
2466 goto errorTreeReturn;
2468 /* if they are both literal then */
2469 /* rewrite the tree */
2470 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2472 tree->type = EX_VALUE;
2473 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2474 valFromType (RETYPE (tree)));
2475 tree->right = tree->left = NULL;
2476 TETYPE (tree) = getSpec (TTYPE (tree) =
2477 tree->opval.val->type);
2481 /* if the right is a pointer or left is a literal
2482 xchange left & right */
2483 if (IS_ARRAY (RTYPE (tree)) ||
2484 IS_PTR (RTYPE (tree)) ||
2485 IS_LITERAL (LTYPE (tree)))
2487 ast *tTree = tree->left;
2488 tree->left = tree->right;
2489 tree->right = tTree;
2492 LRVAL (tree) = RRVAL (tree) = 1;
2493 /* if the left is a pointer */
2494 if (IS_PTR (LTYPE (tree)))
2495 TETYPE (tree) = getSpec (TTYPE (tree) =
2498 TETYPE (tree) = getSpec (TTYPE (tree) =
2499 computeType (LTYPE (tree),
2503 /*------------------------------------------------------------------*/
2504 /*----------------------------*/
2506 /*----------------------------*/
2507 case '-': /* can be unary */
2508 /* if right is null then unary */
2512 if (!IS_ARITHMETIC (LTYPE (tree)))
2514 werror (E_UNARY_OP, tree->opval.op);
2515 goto errorTreeReturn;
2518 /* if left is a literal then do it */
2519 if (IS_LITERAL (LTYPE (tree)))
2521 tree->type = EX_VALUE;
2522 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2524 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2525 SPEC_USIGN(TETYPE(tree)) = 0;
2529 TTYPE (tree) = LTYPE (tree);
2533 /*------------------------------------------------------------------*/
2534 /*----------------------------*/
2536 /*----------------------------*/
2538 if (!(IS_PTR (LTYPE (tree)) ||
2539 IS_ARRAY (LTYPE (tree)) ||
2540 IS_ARITHMETIC (LTYPE (tree))))
2542 werror (E_PLUS_INVALID, "-");
2543 goto errorTreeReturn;
2546 if (!(IS_PTR (RTYPE (tree)) ||
2547 IS_ARRAY (RTYPE (tree)) ||
2548 IS_ARITHMETIC (RTYPE (tree))))
2550 werror (E_PLUS_INVALID, "-");
2551 goto errorTreeReturn;
2554 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2555 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2556 IS_INTEGRAL (RTYPE (tree))))
2558 werror (E_PLUS_INVALID, "-");
2559 goto errorTreeReturn;
2562 /* if they are both literal then */
2563 /* rewrite the tree */
2564 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2566 tree->type = EX_VALUE;
2567 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2568 valFromType (RETYPE (tree)));
2569 tree->right = tree->left = NULL;
2570 TETYPE (tree) = getSpec (TTYPE (tree) =
2571 tree->opval.val->type);
2575 /* if the left & right are equal then zero */
2576 if (isAstEqual (tree->left, tree->right))
2578 tree->type = EX_VALUE;
2579 tree->left = tree->right = NULL;
2580 tree->opval.val = constVal ("0");
2581 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2585 /* if both of them are pointers or arrays then */
2586 /* the result is going to be an integer */
2587 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2588 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2589 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2591 /* if only the left is a pointer */
2592 /* then result is a pointer */
2593 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2594 TETYPE (tree) = getSpec (TTYPE (tree) =
2597 TETYPE (tree) = getSpec (TTYPE (tree) =
2598 computeType (LTYPE (tree),
2600 LRVAL (tree) = RRVAL (tree) = 1;
2603 /*------------------------------------------------------------------*/
2604 /*----------------------------*/
2606 /*----------------------------*/
2608 /* can be only integral type */
2609 if (!IS_INTEGRAL (LTYPE (tree)))
2611 werror (E_UNARY_OP, tree->opval.op);
2612 goto errorTreeReturn;
2615 /* if left is a literal then do it */
2616 if (IS_LITERAL (LTYPE (tree)))
2618 tree->type = EX_VALUE;
2619 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2621 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2625 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2628 /*------------------------------------------------------------------*/
2629 /*----------------------------*/
2631 /*----------------------------*/
2633 /* can be pointer */
2634 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2635 !IS_PTR (LTYPE (tree)) &&
2636 !IS_ARRAY (LTYPE (tree)))
2638 werror (E_UNARY_OP, tree->opval.op);
2639 goto errorTreeReturn;
2642 /* if left is a literal then do it */
2643 if (IS_LITERAL (LTYPE (tree)))
2645 tree->type = EX_VALUE;
2646 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2648 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2652 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2655 /*------------------------------------------------------------------*/
2656 /*----------------------------*/
2658 /*----------------------------*/
2661 TTYPE (tree) = LTYPE (tree);
2662 TETYPE (tree) = LETYPE (tree);
2666 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2671 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2673 werror (E_SHIFT_OP_INVALID);
2674 werror (E_CONTINUE, "left & right types are ");
2675 printTypeChain (LTYPE (tree), stderr);
2676 fprintf (stderr, ",");
2677 printTypeChain (RTYPE (tree), stderr);
2678 fprintf (stderr, "\n");
2679 goto errorTreeReturn;
2682 /* if they are both literal then */
2683 /* rewrite the tree */
2684 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2686 tree->type = EX_VALUE;
2687 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2688 valFromType (RETYPE (tree)),
2689 (tree->opval.op == LEFT_OP ? 1 : 0));
2690 tree->right = tree->left = NULL;
2691 TETYPE (tree) = getSpec (TTYPE (tree) =
2692 tree->opval.val->type);
2695 /* if only the right side is a literal & we are
2696 shifting more than size of the left operand then zero */
2697 if (IS_LITERAL (RTYPE (tree)) &&
2698 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2699 (getSize (LTYPE (tree)) * 8))
2701 werror (W_SHIFT_CHANGED,
2702 (tree->opval.op == LEFT_OP ? "left" : "right"));
2703 tree->type = EX_VALUE;
2704 tree->left = tree->right = NULL;
2705 tree->opval.val = constVal ("0");
2706 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2709 LRVAL (tree) = RRVAL (tree) = 1;
2710 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2712 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2716 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2720 /*------------------------------------------------------------------*/
2721 /*----------------------------*/
2723 /*----------------------------*/
2724 case CAST: /* change the type */
2725 /* cannot cast to an aggregate type */
2726 if (IS_AGGREGATE (LTYPE (tree)))
2728 werror (E_CAST_ILLEGAL);
2729 goto errorTreeReturn;
2732 /* make sure the type is complete and sane */
2733 checkTypeSanity(LETYPE(tree), "(cast)");
2735 /* if the right is a literal replace the tree */
2736 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2738 tree->type = EX_VALUE;
2740 valCastLiteral (LTYPE (tree),
2741 floatFromVal (valFromType (RETYPE (tree))));
2744 TTYPE (tree) = tree->opval.val->type;
2745 tree->values.literalFromCast = 1;
2749 TTYPE (tree) = LTYPE (tree);
2753 TETYPE (tree) = getSpec (TTYPE (tree));
2757 /*------------------------------------------------------------------*/
2758 /*----------------------------*/
2759 /* logical &&, || */
2760 /*----------------------------*/
2763 /* each must me arithmetic type or be a pointer */
2764 if (!IS_PTR (LTYPE (tree)) &&
2765 !IS_ARRAY (LTYPE (tree)) &&
2766 !IS_INTEGRAL (LTYPE (tree)))
2768 werror (E_COMPARE_OP);
2769 goto errorTreeReturn;
2772 if (!IS_PTR (RTYPE (tree)) &&
2773 !IS_ARRAY (RTYPE (tree)) &&
2774 !IS_INTEGRAL (RTYPE (tree)))
2776 werror (E_COMPARE_OP);
2777 goto errorTreeReturn;
2779 /* if they are both literal then */
2780 /* rewrite the tree */
2781 if (IS_LITERAL (RTYPE (tree)) &&
2782 IS_LITERAL (LTYPE (tree)))
2784 tree->type = EX_VALUE;
2785 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2786 valFromType (RETYPE (tree)),
2788 tree->right = tree->left = NULL;
2789 TETYPE (tree) = getSpec (TTYPE (tree) =
2790 tree->opval.val->type);
2793 LRVAL (tree) = RRVAL (tree) = 1;
2794 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2797 /*------------------------------------------------------------------*/
2798 /*----------------------------*/
2799 /* comparison operators */
2800 /*----------------------------*/
2808 ast *lt = optimizeCompare (tree);
2814 /* if they are pointers they must be castable */
2815 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2817 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2819 werror (E_COMPARE_OP);
2820 fprintf (stderr, "comparing type ");
2821 printTypeChain (LTYPE (tree), stderr);
2822 fprintf (stderr, "to type ");
2823 printTypeChain (RTYPE (tree), stderr);
2824 fprintf (stderr, "\n");
2825 goto errorTreeReturn;
2828 /* else they should be promotable to one another */
2831 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2832 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2834 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2836 werror (E_COMPARE_OP);
2837 fprintf (stderr, "comparing type ");
2838 printTypeChain (LTYPE (tree), stderr);
2839 fprintf (stderr, "to type ");
2840 printTypeChain (RTYPE (tree), stderr);
2841 fprintf (stderr, "\n");
2842 goto errorTreeReturn;
2846 /* if they are both literal then */
2847 /* rewrite the tree */
2848 if (IS_LITERAL (RTYPE (tree)) &&
2849 IS_LITERAL (LTYPE (tree)))
2851 tree->type = EX_VALUE;
2852 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2853 valFromType (RETYPE (tree)),
2855 tree->right = tree->left = NULL;
2856 TETYPE (tree) = getSpec (TTYPE (tree) =
2857 tree->opval.val->type);
2860 LRVAL (tree) = RRVAL (tree) = 1;
2861 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2864 /*------------------------------------------------------------------*/
2865 /*----------------------------*/
2867 /*----------------------------*/
2868 case SIZEOF: /* evaluate wihout code generation */
2869 /* change the type to a integer */
2870 tree->type = EX_VALUE;
2871 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2872 tree->opval.val = constVal (buffer);
2873 tree->right = tree->left = NULL;
2874 TETYPE (tree) = getSpec (TTYPE (tree) =
2875 tree->opval.val->type);
2878 /*------------------------------------------------------------------*/
2879 /*----------------------------*/
2880 /* conditional operator '?' */
2881 /*----------------------------*/
2883 /* the type is value of the colon operator (on the right) */
2884 assert(IS_COLON_OP(tree->right));
2885 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2886 TETYPE (tree) = getSpec (TTYPE (tree));
2890 /* if they don't match we have a problem */
2891 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2893 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2894 goto errorTreeReturn;
2897 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2898 TETYPE (tree) = getSpec (TTYPE (tree));
2902 /*------------------------------------------------------------------*/
2903 /*----------------------------*/
2904 /* assignment operators */
2905 /*----------------------------*/
2908 /* for these it must be both must be integral */
2909 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2910 !IS_ARITHMETIC (RTYPE (tree)))
2912 werror (E_OPS_INTEGRAL);
2913 goto errorTreeReturn;
2916 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2918 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2919 werror (E_CODE_WRITE, " ");
2923 werror (E_LVALUE_REQUIRED, "*= or /=");
2924 goto errorTreeReturn;
2937 /* for these it must be both must be integral */
2938 if (!IS_INTEGRAL (LTYPE (tree)) ||
2939 !IS_INTEGRAL (RTYPE (tree)))
2941 werror (E_OPS_INTEGRAL);
2942 goto errorTreeReturn;
2945 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2947 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2948 werror (E_CODE_WRITE, " ");
2952 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2953 goto errorTreeReturn;
2961 /*------------------------------------------------------------------*/
2962 /*----------------------------*/
2964 /*----------------------------*/
2966 if (!(IS_PTR (LTYPE (tree)) ||
2967 IS_ARITHMETIC (LTYPE (tree))))
2969 werror (E_PLUS_INVALID, "-=");
2970 goto errorTreeReturn;
2973 if (!(IS_PTR (RTYPE (tree)) ||
2974 IS_ARITHMETIC (RTYPE (tree))))
2976 werror (E_PLUS_INVALID, "-=");
2977 goto errorTreeReturn;
2980 TETYPE (tree) = getSpec (TTYPE (tree) =
2981 computeType (LTYPE (tree),
2984 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2985 werror (E_CODE_WRITE, " ");
2989 werror (E_LVALUE_REQUIRED, "-=");
2990 goto errorTreeReturn;
2998 /*------------------------------------------------------------------*/
2999 /*----------------------------*/
3001 /*----------------------------*/
3003 /* this is not a unary operation */
3004 /* if both pointers then problem */
3005 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3007 werror (E_PTR_PLUS_PTR);
3008 goto errorTreeReturn;
3011 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3013 werror (E_PLUS_INVALID, "+=");
3014 goto errorTreeReturn;
3017 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3019 werror (E_PLUS_INVALID, "+=");
3020 goto errorTreeReturn;
3023 TETYPE (tree) = getSpec (TTYPE (tree) =
3024 computeType (LTYPE (tree),
3027 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3028 werror (E_CODE_WRITE, " ");
3032 werror (E_LVALUE_REQUIRED, "+=");
3033 goto errorTreeReturn;
3036 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3037 tree->opval.op = '=';
3043 /*------------------------------------------------------------------*/
3044 /*----------------------------*/
3045 /* straight assignemnt */
3046 /*----------------------------*/
3048 /* cannot be an aggregate */
3049 if (IS_AGGREGATE (LTYPE (tree)))
3051 werror (E_AGGR_ASSIGN);
3052 goto errorTreeReturn;
3055 /* they should either match or be castable */
3056 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3058 werror (E_TYPE_MISMATCH, "assignment", " ");
3059 fprintf (stderr, "type --> '");
3060 printTypeChain (RTYPE (tree), stderr);
3061 fprintf (stderr, "' ");
3062 fprintf (stderr, "assigned to type --> '");
3063 printTypeChain (LTYPE (tree), stderr);
3064 fprintf (stderr, "'\n");
3065 goto errorTreeReturn;
3068 /* if the left side of the tree is of type void
3069 then report error */
3070 if (IS_VOID (LTYPE (tree)))
3072 werror (E_CAST_ZERO);
3073 fprintf (stderr, "type --> '");
3074 printTypeChain (RTYPE (tree), stderr);
3075 fprintf (stderr, "' ");
3076 fprintf (stderr, "assigned to type --> '");
3077 printTypeChain (LTYPE (tree), stderr);
3078 fprintf (stderr, "'\n");
3081 /* extra checks for pointer types */
3082 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
3083 !IS_GENPTR (LTYPE (tree)))
3085 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
3086 werror (W_PTR_ASSIGN);
3089 TETYPE (tree) = getSpec (TTYPE (tree) =
3093 if (!tree->initMode ) {
3094 if (IS_CONSTANT (LETYPE (tree))) {
3095 werror (E_CODE_WRITE, " ");
3100 werror (E_LVALUE_REQUIRED, "=");
3101 goto errorTreeReturn;
3108 /*------------------------------------------------------------------*/
3109 /*----------------------------*/
3110 /* comma operator */
3111 /*----------------------------*/
3113 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3116 /*------------------------------------------------------------------*/
3117 /*----------------------------*/
3119 /*----------------------------*/
3123 if (processParms (tree->left,
3125 tree->right, &parmNumber, TRUE))
3126 goto errorTreeReturn;
3128 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3130 tree->left->args = reverseVal (tree->left->args);
3131 reverseParms (tree->right);
3134 tree->args = tree->left->args;
3135 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3138 /*------------------------------------------------------------------*/
3139 /*----------------------------*/
3140 /* return statement */
3141 /*----------------------------*/
3146 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3148 werror (E_RETURN_MISMATCH);
3149 goto errorTreeReturn;
3152 if (IS_VOID (currFunc->type->next)
3154 !IS_VOID (RTYPE (tree)))
3156 werror (E_FUNC_VOID);
3157 goto errorTreeReturn;
3160 /* if there is going to be a casing required then add it */
3161 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3163 #if 0 && defined DEMAND_INTEGER_PROMOTION
3164 if (IS_INTEGRAL (currFunc->type->next))
3166 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3172 decorateType (newNode (CAST,
3173 newAst_LINK (copyLinkChain (currFunc->type->next)),
3183 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3185 werror (E_VOID_FUNC, currFunc->name);
3186 goto errorTreeReturn;
3189 TTYPE (tree) = TETYPE (tree) = NULL;
3192 /*------------------------------------------------------------------*/
3193 /*----------------------------*/
3194 /* switch statement */
3195 /*----------------------------*/
3197 /* the switch value must be an integer */
3198 if (!IS_INTEGRAL (LTYPE (tree)))
3200 werror (E_SWITCH_NON_INTEGER);
3201 goto errorTreeReturn;
3204 TTYPE (tree) = TETYPE (tree) = NULL;
3207 /*------------------------------------------------------------------*/
3208 /*----------------------------*/
3210 /*----------------------------*/
3212 tree->left = backPatchLabels (tree->left,
3215 TTYPE (tree) = TETYPE (tree) = NULL;
3218 /*------------------------------------------------------------------*/
3219 /*----------------------------*/
3221 /*----------------------------*/
3224 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3225 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3226 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3228 /* if the for loop is reversible then
3229 reverse it otherwise do what we normally
3235 if (isLoopReversible (tree, &sym, &init, &end))
3236 return reverseLoop (tree, sym, init, end);
3238 return decorateType (createFor (AST_FOR (tree, trueLabel),
3239 AST_FOR (tree, continueLabel),
3240 AST_FOR (tree, falseLabel),
3241 AST_FOR (tree, condLabel),
3242 AST_FOR (tree, initExpr),
3243 AST_FOR (tree, condExpr),
3244 AST_FOR (tree, loopExpr),
3248 TTYPE (tree) = TETYPE (tree) = NULL;
3252 /* some error found this tree will be killed */
3254 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3255 tree->opval.op = NULLOP;
3261 /*-----------------------------------------------------------------*/
3262 /* sizeofOp - processes size of operation */
3263 /*-----------------------------------------------------------------*/
3265 sizeofOp (sym_link * type)
3269 /* make sure the type is complete and sane */
3270 checkTypeSanity(type, "(sizeof)");
3272 /* get the size and convert it to character */
3273 sprintf (buff, "%d", getSize (type));
3275 /* now convert into value */
3276 return constVal (buff);
3280 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3281 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3282 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3283 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3284 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3285 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3286 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3288 /*-----------------------------------------------------------------*/
3289 /* backPatchLabels - change and or not operators to flow control */
3290 /*-----------------------------------------------------------------*/
3292 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3298 if (!(IS_ANDORNOT (tree)))
3301 /* if this an and */
3304 static int localLbl = 0;
3307 sprintf (buffer, "_and_%d", localLbl++);
3308 localLabel = newSymbol (buffer, NestLevel);
3310 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3312 /* if left is already a IFX then just change the if true label in that */
3313 if (!IS_IFX (tree->left))
3314 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3316 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3317 /* right is a IFX then just join */
3318 if (IS_IFX (tree->right))
3319 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3321 tree->right = createLabel (localLabel, tree->right);
3322 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3324 return newNode (NULLOP, tree->left, tree->right);
3327 /* if this is an or operation */
3330 static int localLbl = 0;
3333 sprintf (buffer, "_or_%d", localLbl++);
3334 localLabel = newSymbol (buffer, NestLevel);
3336 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3338 /* if left is already a IFX then just change the if true label in that */
3339 if (!IS_IFX (tree->left))
3340 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3342 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3343 /* right is a IFX then just join */
3344 if (IS_IFX (tree->right))
3345 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3347 tree->right = createLabel (localLabel, tree->right);
3348 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3350 return newNode (NULLOP, tree->left, tree->right);
3356 int wasnot = IS_NOT (tree->left);
3357 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3359 /* if the left is already a IFX */
3360 if (!IS_IFX (tree->left))
3361 tree->left = newNode (IFX, tree->left, NULL);
3365 tree->left->trueLabel = trueLabel;
3366 tree->left->falseLabel = falseLabel;
3370 tree->left->trueLabel = falseLabel;
3371 tree->left->falseLabel = trueLabel;
3378 tree->trueLabel = trueLabel;
3379 tree->falseLabel = falseLabel;
3386 /*-----------------------------------------------------------------*/
3387 /* createBlock - create expression tree for block */
3388 /*-----------------------------------------------------------------*/
3390 createBlock (symbol * decl, ast * body)
3394 /* if the block has nothing */
3398 ex = newNode (BLOCK, NULL, body);
3399 ex->values.sym = decl;
3401 ex->right = ex->right;
3407 /*-----------------------------------------------------------------*/
3408 /* createLabel - creates the expression tree for labels */
3409 /*-----------------------------------------------------------------*/
3411 createLabel (symbol * label, ast * stmnt)
3414 char name[SDCC_NAME_MAX + 1];
3417 /* must create fresh symbol if the symbol name */
3418 /* exists in the symbol table, since there can */
3419 /* be a variable with the same name as the labl */
3420 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3421 (csym->level == label->level))
3422 label = newSymbol (label->name, label->level);
3424 /* change the name before putting it in add _ */
3425 sprintf (name, "%s", label->name);
3427 /* put the label in the LabelSymbol table */
3428 /* but first check if a label of the same */
3430 if ((csym = findSym (LabelTab, NULL, name)))
3431 werror (E_DUPLICATE_LABEL, label->name);
3433 addSym (LabelTab, label, name, label->level, 0, 0);
3436 label->key = labelKey++;
3437 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3443 /*-----------------------------------------------------------------*/
3444 /* createCase - generates the parsetree for a case statement */
3445 /*-----------------------------------------------------------------*/
3447 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3449 char caseLbl[SDCC_NAME_MAX + 1];
3453 /* if the switch statement does not exist */
3454 /* then case is out of context */
3457 werror (E_CASE_CONTEXT);
3461 caseVal = decorateType (resolveSymbols (caseVal));
3462 /* if not a constant then error */
3463 if (!IS_LITERAL (caseVal->ftype))
3465 werror (E_CASE_CONSTANT);
3469 /* if not a integer than error */
3470 if (!IS_INTEGRAL (caseVal->ftype))
3472 werror (E_CASE_NON_INTEGER);
3476 /* find the end of the switch values chain */
3477 if (!(val = swStat->values.switchVals.swVals))
3478 swStat->values.switchVals.swVals = caseVal->opval.val;
3481 /* also order the cases according to value */
3483 int cVal = (int) floatFromVal (caseVal->opval.val);
3484 while (val && (int) floatFromVal (val) < cVal)
3490 /* if we reached the end then */
3493 pval->next = caseVal->opval.val;
3497 /* we found a value greater than */
3498 /* the current value we must add this */
3499 /* before the value */
3500 caseVal->opval.val->next = val;
3502 /* if this was the first in chain */
3503 if (swStat->values.switchVals.swVals == val)
3504 swStat->values.switchVals.swVals =
3507 pval->next = caseVal->opval.val;
3512 /* create the case label */
3513 sprintf (caseLbl, "_case_%d_%d",
3514 swStat->values.switchVals.swNum,
3515 (int) floatFromVal (caseVal->opval.val));
3517 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3522 /*-----------------------------------------------------------------*/
3523 /* createDefault - creates the parse tree for the default statement */
3524 /*-----------------------------------------------------------------*/
3526 createDefault (ast * swStat, ast * stmnt)
3528 char defLbl[SDCC_NAME_MAX + 1];
3530 /* if the switch statement does not exist */
3531 /* then case is out of context */
3534 werror (E_CASE_CONTEXT);
3538 /* turn on the default flag */
3539 swStat->values.switchVals.swDefault = 1;
3541 /* create the label */
3542 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3543 return createLabel (newSymbol (defLbl, 0), stmnt);
3546 /*-----------------------------------------------------------------*/
3547 /* createIf - creates the parsetree for the if statement */
3548 /*-----------------------------------------------------------------*/
3550 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3552 static int Lblnum = 0;
3554 symbol *ifTrue, *ifFalse, *ifEnd;
3556 /* if neither exists */
3557 if (!elseBody && !ifBody)
3560 /* create the labels */
3561 sprintf (buffer, "_iffalse_%d", Lblnum);
3562 ifFalse = newSymbol (buffer, NestLevel);
3563 /* if no else body then end == false */
3568 sprintf (buffer, "_ifend_%d", Lblnum);
3569 ifEnd = newSymbol (buffer, NestLevel);
3572 sprintf (buffer, "_iftrue_%d", Lblnum);
3573 ifTrue = newSymbol (buffer, NestLevel);
3577 /* attach the ifTrue label to the top of it body */
3578 ifBody = createLabel (ifTrue, ifBody);
3579 /* attach a goto end to the ifBody if else is present */
3582 ifBody = newNode (NULLOP, ifBody,
3584 newAst_VALUE (symbolVal (ifEnd)),
3586 /* put the elseLabel on the else body */
3587 elseBody = createLabel (ifFalse, elseBody);
3588 /* out the end at the end of the body */
3589 elseBody = newNode (NULLOP,
3591 createLabel (ifEnd, NULL));
3595 ifBody = newNode (NULLOP, ifBody,
3596 createLabel (ifFalse, NULL));
3598 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3599 if (IS_IFX (condAst))
3602 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3604 return newNode (NULLOP, ifTree,
3605 newNode (NULLOP, ifBody, elseBody));
3609 /*-----------------------------------------------------------------*/
3610 /* createDo - creates parse tree for do */
3613 /* _docontinue_n: */
3614 /* condition_expression +-> trueLabel -> _dobody_n */
3616 /* +-> falseLabel-> _dobreak_n */
3618 /*-----------------------------------------------------------------*/
3620 createDo (symbol * trueLabel, symbol * continueLabel,
3621 symbol * falseLabel, ast * condAst, ast * doBody)
3626 /* if the body does not exist then it is simple */
3629 condAst = backPatchLabels (condAst, continueLabel, NULL);
3630 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3631 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3632 doTree->trueLabel = continueLabel;
3633 doTree->falseLabel = NULL;
3637 /* otherwise we have a body */
3638 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3640 /* attach the body label to the top */
3641 doBody = createLabel (trueLabel, doBody);
3642 /* attach the continue label to end of body */
3643 doBody = newNode (NULLOP, doBody,
3644 createLabel (continueLabel, NULL));
3646 /* now put the break label at the end */
3647 if (IS_IFX (condAst))
3650 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3652 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3654 /* putting it together */
3655 return newNode (NULLOP, doBody, doTree);
3658 /*-----------------------------------------------------------------*/
3659 /* createFor - creates parse tree for 'for' statement */
3662 /* condExpr +-> trueLabel -> _forbody_n */
3664 /* +-> falseLabel-> _forbreak_n */
3667 /* _forcontinue_n: */
3669 /* goto _forcond_n ; */
3671 /*-----------------------------------------------------------------*/
3673 createFor (symbol * trueLabel, symbol * continueLabel,
3674 symbol * falseLabel, symbol * condLabel,
3675 ast * initExpr, ast * condExpr, ast * loopExpr,
3680 /* if loopexpression not present then we can generate it */
3681 /* the same way as a while */
3683 return newNode (NULLOP, initExpr,
3684 createWhile (trueLabel, continueLabel,
3685 falseLabel, condExpr, forBody));
3686 /* vanilla for statement */
3687 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3689 if (condExpr && !IS_IFX (condExpr))
3690 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3693 /* attach condition label to condition */
3694 condExpr = createLabel (condLabel, condExpr);
3696 /* attach body label to body */
3697 forBody = createLabel (trueLabel, forBody);
3699 /* attach continue to forLoop expression & attach */
3700 /* goto the forcond @ and of loopExpression */
3701 loopExpr = createLabel (continueLabel,
3705 newAst_VALUE (symbolVal (condLabel)),
3707 /* now start putting them together */
3708 forTree = newNode (NULLOP, initExpr, condExpr);
3709 forTree = newNode (NULLOP, forTree, forBody);
3710 forTree = newNode (NULLOP, forTree, loopExpr);
3711 /* finally add the break label */
3712 forTree = newNode (NULLOP, forTree,
3713 createLabel (falseLabel, NULL));
3717 /*-----------------------------------------------------------------*/
3718 /* createWhile - creates parse tree for while statement */
3719 /* the while statement will be created as follows */
3721 /* _while_continue_n: */
3722 /* condition_expression +-> trueLabel -> _while_boby_n */
3724 /* +-> falseLabel -> _while_break_n */
3725 /* _while_body_n: */
3727 /* goto _while_continue_n */
3728 /* _while_break_n: */
3729 /*-----------------------------------------------------------------*/
3731 createWhile (symbol * trueLabel, symbol * continueLabel,
3732 symbol * falseLabel, ast * condExpr, ast * whileBody)
3736 /* put the continue label */
3737 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3738 condExpr = createLabel (continueLabel, condExpr);
3739 condExpr->lineno = 0;
3741 /* put the body label in front of the body */
3742 whileBody = createLabel (trueLabel, whileBody);
3743 whileBody->lineno = 0;
3744 /* put a jump to continue at the end of the body */
3745 /* and put break label at the end of the body */
3746 whileBody = newNode (NULLOP,
3749 newAst_VALUE (symbolVal (continueLabel)),
3750 createLabel (falseLabel, NULL)));
3752 /* put it all together */
3753 if (IS_IFX (condExpr))
3754 whileTree = condExpr;
3757 whileTree = newNode (IFX, condExpr, NULL);
3758 /* put the true & false labels in place */
3759 whileTree->trueLabel = trueLabel;
3760 whileTree->falseLabel = falseLabel;
3763 return newNode (NULLOP, whileTree, whileBody);
3766 /*-----------------------------------------------------------------*/
3767 /* optimizeGetHbit - get highest order bit of the expression */
3768 /*-----------------------------------------------------------------*/
3770 optimizeGetHbit (ast * tree)
3773 /* if this is not a bit and */
3774 if (!IS_BITAND (tree))
3777 /* will look for tree of the form
3778 ( expr >> ((sizeof expr) -1) ) & 1 */
3779 if (!IS_AST_LIT_VALUE (tree->right))
3782 if (AST_LIT_VALUE (tree->right) != 1)
3785 if (!IS_RIGHT_OP (tree->left))
3788 if (!IS_AST_LIT_VALUE (tree->left->right))
3791 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3792 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3795 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3799 /*-----------------------------------------------------------------*/
3800 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3801 /*-----------------------------------------------------------------*/
3803 optimizeRRCRLC (ast * root)
3805 /* will look for trees of the form
3806 (?expr << 1) | (?expr >> 7) or
3807 (?expr >> 7) | (?expr << 1) will make that
3808 into a RLC : operation ..
3810 (?expr >> 1) | (?expr << 7) or
3811 (?expr << 7) | (?expr >> 1) will make that
3812 into a RRC operation
3813 note : by 7 I mean (number of bits required to hold the
3815 /* if the root operations is not a | operation the not */
3816 if (!IS_BITOR (root))
3819 /* I have to think of a better way to match patterns this sucks */
3820 /* that aside let start looking for the first case : I use a the
3821 negative check a lot to improve the efficiency */
3822 /* (?expr << 1) | (?expr >> 7) */
3823 if (IS_LEFT_OP (root->left) &&
3824 IS_RIGHT_OP (root->right))
3827 if (!SPEC_USIGN (TETYPE (root->left->left)))
3830 if (!IS_AST_LIT_VALUE (root->left->right) ||
3831 !IS_AST_LIT_VALUE (root->right->right))
3834 /* make sure it is the same expression */
3835 if (!isAstEqual (root->left->left,
3839 if (AST_LIT_VALUE (root->left->right) != 1)
3842 if (AST_LIT_VALUE (root->right->right) !=
3843 (getSize (TTYPE (root->left->left)) * 8 - 1))
3846 /* whew got the first case : create the AST */
3847 return newNode (RLC, root->left->left, NULL);
3851 /* check for second case */
3852 /* (?expr >> 7) | (?expr << 1) */
3853 if (IS_LEFT_OP (root->right) &&
3854 IS_RIGHT_OP (root->left))
3857 if (!SPEC_USIGN (TETYPE (root->left->left)))
3860 if (!IS_AST_LIT_VALUE (root->left->right) ||
3861 !IS_AST_LIT_VALUE (root->right->right))
3864 /* make sure it is the same symbol */
3865 if (!isAstEqual (root->left->left,
3869 if (AST_LIT_VALUE (root->right->right) != 1)
3872 if (AST_LIT_VALUE (root->left->right) !=
3873 (getSize (TTYPE (root->left->left)) * 8 - 1))
3876 /* whew got the first case : create the AST */
3877 return newNode (RLC, root->left->left, NULL);
3882 /* third case for RRC */
3883 /* (?symbol >> 1) | (?symbol << 7) */
3884 if (IS_LEFT_OP (root->right) &&
3885 IS_RIGHT_OP (root->left))
3888 if (!SPEC_USIGN (TETYPE (root->left->left)))
3891 if (!IS_AST_LIT_VALUE (root->left->right) ||
3892 !IS_AST_LIT_VALUE (root->right->right))
3895 /* make sure it is the same symbol */
3896 if (!isAstEqual (root->left->left,
3900 if (AST_LIT_VALUE (root->left->right) != 1)
3903 if (AST_LIT_VALUE (root->right->right) !=
3904 (getSize (TTYPE (root->left->left)) * 8 - 1))
3907 /* whew got the first case : create the AST */
3908 return newNode (RRC, root->left->left, NULL);
3912 /* fourth and last case for now */
3913 /* (?symbol << 7) | (?symbol >> 1) */
3914 if (IS_RIGHT_OP (root->right) &&
3915 IS_LEFT_OP (root->left))
3918 if (!SPEC_USIGN (TETYPE (root->left->left)))
3921 if (!IS_AST_LIT_VALUE (root->left->right) ||
3922 !IS_AST_LIT_VALUE (root->right->right))
3925 /* make sure it is the same symbol */
3926 if (!isAstEqual (root->left->left,
3930 if (AST_LIT_VALUE (root->right->right) != 1)
3933 if (AST_LIT_VALUE (root->left->right) !=
3934 (getSize (TTYPE (root->left->left)) * 8 - 1))
3937 /* whew got the first case : create the AST */
3938 return newNode (RRC, root->left->left, NULL);
3942 /* not found return root */
3946 /*-----------------------------------------------------------------*/
3947 /* optimizeCompare - otimizes compares for bit variables */
3948 /*-----------------------------------------------------------------*/
3950 optimizeCompare (ast * root)
3952 ast *optExpr = NULL;
3955 unsigned int litValue;
3957 /* if nothing then return nothing */
3961 /* if not a compare op then do leaves */
3962 if (!IS_COMPARE_OP (root))
3964 root->left = optimizeCompare (root->left);
3965 root->right = optimizeCompare (root->right);
3969 /* if left & right are the same then depending
3970 of the operation do */
3971 if (isAstEqual (root->left, root->right))
3973 switch (root->opval.op)
3978 optExpr = newAst_VALUE (constVal ("0"));
3983 optExpr = newAst_VALUE (constVal ("1"));
3987 return decorateType (optExpr);
3990 vleft = (root->left->type == EX_VALUE ?
3991 root->left->opval.val : NULL);
3993 vright = (root->right->type == EX_VALUE ?
3994 root->right->opval.val : NULL);
3996 /* if left is a BITVAR in BITSPACE */
3997 /* and right is a LITERAL then opt- */
3998 /* imize else do nothing */
3999 if (vleft && vright &&
4000 IS_BITVAR (vleft->etype) &&
4001 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4002 IS_LITERAL (vright->etype))
4005 /* if right side > 1 then comparison may never succeed */
4006 if ((litValue = (int) floatFromVal (vright)) > 1)
4008 werror (W_BAD_COMPARE);
4014 switch (root->opval.op)
4016 case '>': /* bit value greater than 1 cannot be */
4017 werror (W_BAD_COMPARE);
4021 case '<': /* bit value < 1 means 0 */
4023 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4026 case LE_OP: /* bit value <= 1 means no check */
4027 optExpr = newAst_VALUE (vright);
4030 case GE_OP: /* bit value >= 1 means only check for = */
4032 optExpr = newAst_VALUE (vleft);
4037 { /* literal is zero */
4038 switch (root->opval.op)
4040 case '<': /* bit value < 0 cannot be */
4041 werror (W_BAD_COMPARE);
4045 case '>': /* bit value > 0 means 1 */
4047 optExpr = newAst_VALUE (vleft);
4050 case LE_OP: /* bit value <= 0 means no check */
4051 case GE_OP: /* bit value >= 0 means no check */
4052 werror (W_BAD_COMPARE);
4056 case EQ_OP: /* bit == 0 means ! of bit */
4057 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4061 return decorateType (resolveSymbols (optExpr));
4062 } /* end-of-if of BITVAR */
4067 /*-----------------------------------------------------------------*/
4068 /* addSymToBlock : adds the symbol to the first block we find */
4069 /*-----------------------------------------------------------------*/
4071 addSymToBlock (symbol * sym, ast * tree)
4073 /* reached end of tree or a leaf */
4074 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4078 if (IS_AST_OP (tree) &&
4079 tree->opval.op == BLOCK)
4082 symbol *lsym = copySymbol (sym);
4084 lsym->next = AST_VALUES (tree, sym);
4085 AST_VALUES (tree, sym) = lsym;
4089 addSymToBlock (sym, tree->left);
4090 addSymToBlock (sym, tree->right);
4093 /*-----------------------------------------------------------------*/
4094 /* processRegParms - do processing for register parameters */
4095 /*-----------------------------------------------------------------*/
4097 processRegParms (value * args, ast * body)
4101 if (IS_REGPARM (args->etype))
4102 addSymToBlock (args->sym, body);
4107 /*-----------------------------------------------------------------*/
4108 /* resetParmKey - resets the operandkeys for the symbols */
4109 /*-----------------------------------------------------------------*/
4110 DEFSETFUNC (resetParmKey)
4121 /*-----------------------------------------------------------------*/
4122 /* createFunction - This is the key node that calls the iCode for */
4123 /* generating the code for a function. Note code */
4124 /* is generated function by function, later when */
4125 /* add inter-procedural analysis this will change */
4126 /*-----------------------------------------------------------------*/
4128 createFunction (symbol * name, ast * body)
4134 iCode *piCode = NULL;
4136 /* if check function return 0 then some problem */
4137 if (checkFunction (name) == 0)
4140 /* create a dummy block if none exists */
4142 body = newNode (BLOCK, NULL, NULL);
4146 /* check if the function name already in the symbol table */
4147 if ((csym = findSym (SymbolTab, NULL, name->name)))
4150 /* special case for compiler defined functions
4151 we need to add the name to the publics list : this
4152 actually means we are now compiling the compiler
4156 addSet (&publics, name);
4162 allocVariables (name);
4164 name->lastLine = yylineno;
4166 processFuncArgs (currFunc, 0);
4168 /* set the stack pointer */
4169 /* PENDING: check this for the mcs51 */
4170 stackPtr = -port->stack.direction * port->stack.call_overhead;
4171 if (IS_ISR (name->etype))
4172 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4173 if (IS_RENT (name->etype) || options.stackAuto)
4174 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4176 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4178 fetype = getSpec (name->type); /* get the specifier for the function */
4179 /* if this is a reentrant function then */
4180 if (IS_RENT (fetype))
4183 allocParms (name->args); /* allocate the parameters */
4185 /* do processing for parameters that are passed in registers */
4186 processRegParms (name->args, body);
4188 /* set the stack pointer */
4192 /* allocate & autoinit the block variables */
4193 processBlockVars (body, &stack, ALLOCATE);
4195 /* save the stack information */
4196 if (options.useXstack)
4197 name->xstack = SPEC_STAK (fetype) = stack;
4199 name->stack = SPEC_STAK (fetype) = stack;
4201 /* name needs to be mangled */
4202 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4204 body = resolveSymbols (body); /* resolve the symbols */
4205 body = decorateType (body); /* propagateType & do semantic checks */
4207 ex = newAst_VALUE (symbolVal (name)); /* create name */
4208 ex = newNode (FUNCTION, ex, body);
4209 ex->values.args = name->args;
4213 werror (E_FUNC_NO_CODE, name->name);
4217 /* create the node & generate intermediate code */
4219 codeOutFile = code->oFile;
4220 piCode = iCodeFromAst (ex);
4224 werror (E_FUNC_NO_CODE, name->name);
4228 eBBlockFromiCode (piCode);
4230 /* if there are any statics then do them */
4233 GcurMemmap = statsg;
4234 codeOutFile = statsg->oFile;
4235 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4241 /* dealloc the block variables */
4242 processBlockVars (body, &stack, DEALLOCATE);
4243 /* deallocate paramaters */
4244 deallocParms (name->args);
4246 if (IS_RENT (fetype))
4249 /* we are done freeup memory & cleanup */
4254 addSet (&operKeyReset, name);
4255 applyToSet (operKeyReset, resetParmKey);
4258 cdbStructBlock (1, cdbFile);
4260 cleanUpLevel (LabelTab, 0);
4261 cleanUpBlock (StructTab, 1);
4262 cleanUpBlock (TypedefTab, 1);
4264 xstack->syms = NULL;
4265 istack->syms = NULL;
4270 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4271 /*-----------------------------------------------------------------*/
4272 /* ast_print : prints the ast (for debugging purposes) */
4273 /*-----------------------------------------------------------------*/
4275 void ast_print (ast * tree, FILE *outfile, int indent)
4280 /* can print only decorated trees */
4281 if (!tree->decorated) return;
4283 /* if any child is an error | this one is an error do nothing */
4284 if (tree->isError ||
4285 (tree->left && tree->left->isError) ||
4286 (tree->right && tree->right->isError)) {
4287 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4291 /* print the line */
4292 /* if not block & function */
4293 if (tree->type == EX_OP &&
4294 (tree->opval.op != FUNCTION &&
4295 tree->opval.op != BLOCK &&
4296 tree->opval.op != NULLOP)) {
4299 if (tree->opval.op == FUNCTION) {
4300 fprintf(outfile,"FUNCTION (%p) type (",tree);
4301 printTypeChain (tree->ftype,outfile);
4302 fprintf(outfile,")\n");
4303 ast_print(tree->left,outfile,indent+4);
4304 ast_print(tree->right,outfile,indent+4);
4307 if (tree->opval.op == BLOCK) {
4308 symbol *decls = tree->values.sym;
4309 fprintf(outfile,"{\n");
4311 INDENT(indent+4,outfile);
4312 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4313 printTypeChain(decls->type,outfile);
4314 fprintf(outfile,")\n");
4316 decls = decls->next;
4318 ast_print(tree->right,outfile,indent+4);
4319 fprintf(outfile,"}\n");
4322 if (tree->opval.op == NULLOP) {
4323 fprintf(outfile,"\n");
4324 ast_print(tree->left,outfile,indent);
4325 fprintf(outfile,"\n");
4326 ast_print(tree->right,outfile,indent);
4329 INDENT(indent,outfile);
4331 /*------------------------------------------------------------------*/
4332 /*----------------------------*/
4333 /* leaf has been reached */
4334 /*----------------------------*/
4335 /* if this is of type value */
4336 /* just get the type */
4337 if (tree->type == EX_VALUE) {
4339 if (IS_LITERAL (tree->opval.val->etype)) {
4340 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4341 (int) floatFromVal(tree->opval.val),
4342 (int) floatFromVal(tree->opval.val),
4343 floatFromVal(tree->opval.val));
4344 } else if (tree->opval.val->sym) {
4345 /* if the undefined flag is set then give error message */
4346 if (tree->opval.val->sym->undefined) {
4347 fprintf(outfile,"UNDEFINED SYMBOL ");
4349 fprintf(outfile,"SYMBOL ");
4351 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4354 fprintf(outfile," type (");
4355 printTypeChain(tree->ftype,outfile);
4356 fprintf(outfile,")\n");
4358 fprintf(outfile,"\n");
4363 /* if type link for the case of cast */
4364 if (tree->type == EX_LINK) {
4365 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4366 printTypeChain(tree->opval.lnk,outfile);
4367 fprintf(outfile,")\n");
4372 /* depending on type of operator do */
4374 switch (tree->opval.op) {
4375 /*------------------------------------------------------------------*/
4376 /*----------------------------*/
4378 /*----------------------------*/
4380 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4381 printTypeChain(tree->ftype,outfile);
4382 fprintf(outfile,")\n");
4383 ast_print(tree->left,outfile,indent+4);
4384 ast_print(tree->right,outfile,indent+4);
4387 /*------------------------------------------------------------------*/
4388 /*----------------------------*/
4390 /*----------------------------*/
4392 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4393 printTypeChain(tree->ftype,outfile);
4394 fprintf(outfile,")\n");
4395 ast_print(tree->left,outfile,indent+4);
4396 ast_print(tree->right,outfile,indent+4);
4399 /*------------------------------------------------------------------*/
4400 /*----------------------------*/
4401 /* struct/union pointer */
4402 /*----------------------------*/
4404 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4405 printTypeChain(tree->ftype,outfile);
4406 fprintf(outfile,")\n");
4407 ast_print(tree->left,outfile,indent+4);
4408 ast_print(tree->right,outfile,indent+4);
4411 /*------------------------------------------------------------------*/
4412 /*----------------------------*/
4413 /* ++/-- operation */
4414 /*----------------------------*/
4415 case INC_OP: /* incerement operator unary so left only */
4416 fprintf(outfile,"INC_OP (%p) type (",tree);
4417 printTypeChain(tree->ftype,outfile);
4418 fprintf(outfile,")\n");
4419 ast_print(tree->left,outfile,indent+4);
4423 fprintf(outfile,"DEC_OP (%p) type (",tree);
4424 printTypeChain(tree->ftype,outfile);
4425 fprintf(outfile,")\n");
4426 ast_print(tree->left,outfile,indent+4);
4429 /*------------------------------------------------------------------*/
4430 /*----------------------------*/
4432 /*----------------------------*/
4435 fprintf(outfile,"& (%p) type (",tree);
4436 printTypeChain(tree->ftype,outfile);
4437 fprintf(outfile,")\n");
4438 ast_print(tree->left,outfile,indent+4);
4439 ast_print(tree->right,outfile,indent+4);
4441 fprintf(outfile,"ADDRESS_OF (%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);
4448 /*----------------------------*/
4450 /*----------------------------*/
4452 fprintf(outfile,"OR (%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);
4458 /*------------------------------------------------------------------*/
4459 /*----------------------------*/
4461 /*----------------------------*/
4463 fprintf(outfile,"XOR (%p) type (",tree);
4464 printTypeChain(tree->ftype,outfile);
4465 fprintf(outfile,")\n");
4466 ast_print(tree->left,outfile,indent+4);
4467 ast_print(tree->right,outfile,indent+4);
4470 /*------------------------------------------------------------------*/
4471 /*----------------------------*/
4473 /*----------------------------*/
4475 fprintf(outfile,"DIV (%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);
4481 /*------------------------------------------------------------------*/
4482 /*----------------------------*/
4484 /*----------------------------*/
4486 fprintf(outfile,"MOD (%p) type (",tree);
4487 printTypeChain(tree->ftype,outfile);
4488 fprintf(outfile,")\n");
4489 ast_print(tree->left,outfile,indent+4);
4490 ast_print(tree->right,outfile,indent+4);
4493 /*------------------------------------------------------------------*/
4494 /*----------------------------*/
4495 /* address dereference */
4496 /*----------------------------*/
4497 case '*': /* can be unary : if right is null then unary operation */
4499 fprintf(outfile,"DEREF (%p) type (",tree);
4500 printTypeChain(tree->ftype,outfile);
4501 fprintf(outfile,")\n");
4502 ast_print(tree->left,outfile,indent+4);
4505 /*------------------------------------------------------------------*/
4506 /*----------------------------*/
4507 /* multiplication */
4508 /*----------------------------*/
4509 fprintf(outfile,"MULT (%p) type (",tree);
4510 printTypeChain(tree->ftype,outfile);
4511 fprintf(outfile,")\n");
4512 ast_print(tree->left,outfile,indent+4);
4513 ast_print(tree->right,outfile,indent+4);
4517 /*------------------------------------------------------------------*/
4518 /*----------------------------*/
4519 /* unary '+' operator */
4520 /*----------------------------*/
4524 fprintf(outfile,"UPLUS (%p) type (",tree);
4525 printTypeChain(tree->ftype,outfile);
4526 fprintf(outfile,")\n");
4527 ast_print(tree->left,outfile,indent+4);
4529 /*------------------------------------------------------------------*/
4530 /*----------------------------*/
4532 /*----------------------------*/
4533 fprintf(outfile,"ADD (%p) type (",tree);
4534 printTypeChain(tree->ftype,outfile);
4535 fprintf(outfile,")\n");
4536 ast_print(tree->left,outfile,indent+4);
4537 ast_print(tree->right,outfile,indent+4);
4540 /*------------------------------------------------------------------*/
4541 /*----------------------------*/
4543 /*----------------------------*/
4544 case '-': /* can be unary */
4546 fprintf(outfile,"UMINUS (%p) type (",tree);
4547 printTypeChain(tree->ftype,outfile);
4548 fprintf(outfile,")\n");
4549 ast_print(tree->left,outfile,indent+4);
4551 /*------------------------------------------------------------------*/
4552 /*----------------------------*/
4554 /*----------------------------*/
4555 fprintf(outfile,"SUB (%p) type (",tree);
4556 printTypeChain(tree->ftype,outfile);
4557 fprintf(outfile,")\n");
4558 ast_print(tree->left,outfile,indent+4);
4559 ast_print(tree->right,outfile,indent+4);
4562 /*------------------------------------------------------------------*/
4563 /*----------------------------*/
4565 /*----------------------------*/
4567 fprintf(outfile,"COMPL (%p) type (",tree);
4568 printTypeChain(tree->ftype,outfile);
4569 fprintf(outfile,")\n");
4570 ast_print(tree->left,outfile,indent+4);
4572 /*------------------------------------------------------------------*/
4573 /*----------------------------*/
4575 /*----------------------------*/
4577 fprintf(outfile,"NOT (%p) type (",tree);
4578 printTypeChain(tree->ftype,outfile);
4579 fprintf(outfile,")\n");
4580 ast_print(tree->left,outfile,indent+4);
4582 /*------------------------------------------------------------------*/
4583 /*----------------------------*/
4585 /*----------------------------*/
4587 fprintf(outfile,"RRC (%p) type (",tree);
4588 printTypeChain(tree->ftype,outfile);
4589 fprintf(outfile,")\n");
4590 ast_print(tree->left,outfile,indent+4);
4594 fprintf(outfile,"RLC (%p) type (",tree);
4595 printTypeChain(tree->ftype,outfile);
4596 fprintf(outfile,")\n");
4597 ast_print(tree->left,outfile,indent+4);
4600 fprintf(outfile,"GETHBIT (%p) type (",tree);
4601 printTypeChain(tree->ftype,outfile);
4602 fprintf(outfile,")\n");
4603 ast_print(tree->left,outfile,indent+4);
4606 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4607 printTypeChain(tree->ftype,outfile);
4608 fprintf(outfile,")\n");
4609 ast_print(tree->left,outfile,indent+4);
4610 ast_print(tree->right,outfile,indent+4);
4613 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4614 printTypeChain(tree->ftype,outfile);
4615 fprintf(outfile,")\n");
4616 ast_print(tree->left,outfile,indent+4);
4617 ast_print(tree->right,outfile,indent+4);
4619 /*------------------------------------------------------------------*/
4620 /*----------------------------*/
4622 /*----------------------------*/
4623 case CAST: /* change the type */
4624 fprintf(outfile,"CAST (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->right,outfile,indent+4);
4631 fprintf(outfile,"ANDAND (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+4);
4635 ast_print(tree->right,outfile,indent+4);
4638 fprintf(outfile,"OROR (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+4);
4642 ast_print(tree->right,outfile,indent+4);
4645 /*------------------------------------------------------------------*/
4646 /*----------------------------*/
4647 /* comparison operators */
4648 /*----------------------------*/
4650 fprintf(outfile,"GT(>) (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+4);
4654 ast_print(tree->right,outfile,indent+4);
4657 fprintf(outfile,"LT(<) (%p) type (",tree);
4658 printTypeChain(tree->ftype,outfile);
4659 fprintf(outfile,")\n");
4660 ast_print(tree->left,outfile,indent+4);
4661 ast_print(tree->right,outfile,indent+4);
4664 fprintf(outfile,"LE(<=) (%p) type (",tree);
4665 printTypeChain(tree->ftype,outfile);
4666 fprintf(outfile,")\n");
4667 ast_print(tree->left,outfile,indent+4);
4668 ast_print(tree->right,outfile,indent+4);
4671 fprintf(outfile,"GE(>=) (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+4);
4675 ast_print(tree->right,outfile,indent+4);
4678 fprintf(outfile,"EQ(==) (%p) type (",tree);
4679 printTypeChain(tree->ftype,outfile);
4680 fprintf(outfile,")\n");
4681 ast_print(tree->left,outfile,indent+4);
4682 ast_print(tree->right,outfile,indent+4);
4685 fprintf(outfile,"NE(!=) (%p) type (",tree);
4686 printTypeChain(tree->ftype,outfile);
4687 fprintf(outfile,")\n");
4688 ast_print(tree->left,outfile,indent+4);
4689 ast_print(tree->right,outfile,indent+4);
4690 /*------------------------------------------------------------------*/
4691 /*----------------------------*/
4693 /*----------------------------*/
4694 case SIZEOF: /* evaluate wihout code generation */
4695 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4698 /*------------------------------------------------------------------*/
4699 /*----------------------------*/
4700 /* conditional operator '?' */
4701 /*----------------------------*/
4703 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+4);
4707 ast_print(tree->right,outfile,indent+4);
4710 fprintf(outfile,"COLON(:) (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+4);
4714 ast_print(tree->right,outfile,indent+4);
4717 /*------------------------------------------------------------------*/
4718 /*----------------------------*/
4719 /* assignment operators */
4720 /*----------------------------*/
4722 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4723 printTypeChain(tree->ftype,outfile);
4724 fprintf(outfile,")\n");
4725 ast_print(tree->left,outfile,indent+4);
4726 ast_print(tree->right,outfile,indent+4);
4729 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4730 printTypeChain(tree->ftype,outfile);
4731 fprintf(outfile,")\n");
4732 ast_print(tree->left,outfile,indent+4);
4733 ast_print(tree->right,outfile,indent+4);
4736 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4737 printTypeChain(tree->ftype,outfile);
4738 fprintf(outfile,")\n");
4739 ast_print(tree->left,outfile,indent+4);
4740 ast_print(tree->right,outfile,indent+4);
4743 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4744 printTypeChain(tree->ftype,outfile);
4745 fprintf(outfile,")\n");
4746 ast_print(tree->left,outfile,indent+4);
4747 ast_print(tree->right,outfile,indent+4);
4750 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4751 printTypeChain(tree->ftype,outfile);
4752 fprintf(outfile,")\n");
4753 ast_print(tree->left,outfile,indent+4);
4754 ast_print(tree->right,outfile,indent+4);
4757 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4758 printTypeChain(tree->ftype,outfile);
4759 fprintf(outfile,")\n");
4760 ast_print(tree->left,outfile,indent+4);
4761 ast_print(tree->right,outfile,indent+4);
4764 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4765 printTypeChain(tree->ftype,outfile);
4766 fprintf(outfile,")\n");
4767 ast_print(tree->left,outfile,indent+4);
4768 ast_print(tree->right,outfile,indent+4);
4770 /*------------------------------------------------------------------*/
4771 /*----------------------------*/
4773 /*----------------------------*/
4775 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4776 printTypeChain(tree->ftype,outfile);
4777 fprintf(outfile,")\n");
4778 ast_print(tree->left,outfile,indent+4);
4779 ast_print(tree->right,outfile,indent+4);
4781 /*------------------------------------------------------------------*/
4782 /*----------------------------*/
4784 /*----------------------------*/
4786 fprintf(outfile,"ADDASS(+=) (%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);
4792 /*------------------------------------------------------------------*/
4793 /*----------------------------*/
4794 /* straight assignemnt */
4795 /*----------------------------*/
4797 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4798 printTypeChain(tree->ftype,outfile);
4799 fprintf(outfile,")\n");
4800 ast_print(tree->left,outfile,indent+4);
4801 ast_print(tree->right,outfile,indent+4);
4803 /*------------------------------------------------------------------*/
4804 /*----------------------------*/
4805 /* comma operator */
4806 /*----------------------------*/
4808 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4809 printTypeChain(tree->ftype,outfile);
4810 fprintf(outfile,")\n");
4811 ast_print(tree->left,outfile,indent+4);
4812 ast_print(tree->right,outfile,indent+4);
4814 /*------------------------------------------------------------------*/
4815 /*----------------------------*/
4817 /*----------------------------*/
4820 fprintf(outfile,"CALL (%p) type (",tree);
4821 printTypeChain(tree->ftype,outfile);
4822 fprintf(outfile,")\n");
4823 ast_print(tree->left,outfile,indent+4);
4824 ast_print(tree->right,outfile,indent+4);
4827 fprintf(outfile,"PARM ");
4828 ast_print(tree->left,outfile,indent+4);
4829 if (tree->right && !IS_AST_PARAM(tree->right)) {
4830 fprintf(outfile,"PARM ");
4831 ast_print(tree->right,outfile,indent+4);
4834 /*------------------------------------------------------------------*/
4835 /*----------------------------*/
4836 /* return statement */
4837 /*----------------------------*/
4839 fprintf(outfile,"RETURN (%p) type (",tree);
4840 printTypeChain(tree->right->ftype,outfile);
4841 fprintf(outfile,")\n");
4842 ast_print(tree->right,outfile,indent+4);
4844 /*------------------------------------------------------------------*/
4845 /*----------------------------*/
4846 /* label statement */
4847 /*----------------------------*/
4849 fprintf(outfile,"LABEL (%p)",tree);
4850 ast_print(tree->left,outfile,indent+4);
4851 ast_print(tree->right,outfile,indent);
4853 /*------------------------------------------------------------------*/
4854 /*----------------------------*/
4855 /* switch statement */
4856 /*----------------------------*/
4860 fprintf(outfile,"SWITCH (%p) ",tree);
4861 ast_print(tree->left,outfile,0);
4862 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4863 INDENT(indent+4,outfile);
4864 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4865 (int) floatFromVal(val),
4866 tree->values.switchVals.swNum,
4867 (int) floatFromVal(val));
4869 ast_print(tree->right,outfile,indent);
4872 /*------------------------------------------------------------------*/
4873 /*----------------------------*/
4875 /*----------------------------*/
4877 ast_print(tree->left,outfile,indent);
4878 INDENT(indent,outfile);
4879 fprintf(outfile,"IF (%p) \n",tree);
4880 if (tree->trueLabel) {
4881 INDENT(indent,outfile);
4882 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4884 if (tree->falseLabel) {
4885 INDENT(indent,outfile);
4886 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4888 ast_print(tree->right,outfile,indent);
4890 /*------------------------------------------------------------------*/
4891 /*----------------------------*/
4893 /*----------------------------*/
4895 fprintf(outfile,"FOR (%p) \n",tree);
4896 if (AST_FOR( tree, initExpr)) {
4897 INDENT(indent+4,outfile);
4898 fprintf(outfile,"INIT EXPR ");
4899 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4901 if (AST_FOR( tree, condExpr)) {
4902 INDENT(indent+4,outfile);
4903 fprintf(outfile,"COND EXPR ");
4904 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4906 if (AST_FOR( tree, loopExpr)) {
4907 INDENT(indent+4,outfile);
4908 fprintf(outfile,"LOOP EXPR ");
4909 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4911 fprintf(outfile,"FOR LOOP BODY \n");
4912 ast_print(tree->left,outfile,indent+4);
4921 ast_print(t,stdout,1);