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) {
1040 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1042 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1043 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1044 "with -mmcs51 and --model-large\n");
1048 if (SPEC_OCLS(sym->type->next)!=xdata) {
1049 fprintf (stderr, "Can't \"TRY_THE_NEW_INITALIZER\" unless in xdata\n");
1053 if (getSize(sym->type) > 64) { // else it is'n worth it: do it the old way
1054 // emit the inital values in cseg, then copy it to where it belongs
1056 int count, size=getSize(sym->type->next);
1058 if (ival->type != INIT_DEEP) {
1059 werror (E_INIT_STRUCT, sym->name);
1063 tfprintf (code->oFile, "; initial data for %s\n", sym->name);
1064 // TODO: this has to be a unique name
1065 tfprintf (code->oFile, "_init_%s:", sym->name);
1067 for (count=0, iLoop=ival->init.deep; iLoop; iLoop=iLoop->next) {
1069 printIval (sym, sym->type->next, iLoop, code->oFile);
1072 // Now we only have to copy <count> bytes from cseg.
1073 // This is VERY -mmcs51 --model-large specific for now,
1074 // in fact we should generate
1075 // some icodes here that does the trick. But ok: experimental
1076 // Trick: memcpy (sym->name, _init_(sym->name), count)
1077 fprintf (statsg->oFile, "; %s %d\n", filename, sym->lineDef);
1078 fprintf (statsg->oFile, "; copy initial data from cseg _init_%s to %s\n",
1079 sym->name, sym->name);
1080 fprintf (statsg->oFile, " mov dptr,#_memcpy_PARM_2\n");
1081 fprintf (statsg->oFile, " mov a,#_%s\n", sym->name);
1082 fprintf (statsg->oFile, " movx @dptr,a\n");
1083 fprintf (statsg->oFile, " inc dptr\n");
1084 fprintf (statsg->oFile, " mov a,#(_%s>>8)\n", sym->name);
1085 fprintf (statsg->oFile, " movx @dptr,a\n");
1086 fprintf (statsg->oFile, " inc dptr\n");
1087 fprintf (statsg->oFile, " mov a,#%02x; from cseg\n", 1);
1088 fprintf (statsg->oFile, " movx @dptr,a\n");
1089 fprintf (statsg->oFile, " mov dptr,#_memcpy_PARM_3\n");
1090 fprintf (statsg->oFile, " mov a,#(%d>>0); number of bytes\n", count);
1091 fprintf (statsg->oFile, " movx @dptr,a\n");
1092 fprintf (statsg->oFile, " inc dptr\n");
1093 fprintf (statsg->oFile, " mov a,#(%d>>8)\n", count);
1094 fprintf (statsg->oFile, " movx @dptr,a\n");
1095 fprintf (statsg->oFile, " mov dptr,#_init_%s\n", sym->name);
1096 fprintf (statsg->oFile, " mov b,#%02x; only to xseg for now\n", 2);
1097 fprintf (statsg->oFile, " lcall _memcpy\n");
1103 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1106 /*-----------------------------------------------------------------*/
1107 /* gatherAutoInit - creates assignment expressions for initial */
1109 /*-----------------------------------------------------------------*/
1111 gatherAutoInit (symbol * autoChain)
1118 for (sym = autoChain; sym; sym = sym->next)
1121 /* resolve the symbols in the ival */
1123 resolveIvalSym (sym->ival);
1125 /* if this is a static variable & has an */
1126 /* initial value the code needs to be lifted */
1127 /* here to the main portion since they can be */
1128 /* initialised only once at the start */
1129 if (IS_STATIC (sym->etype) && sym->ival &&
1130 SPEC_SCLS (sym->etype) != S_CODE)
1134 // this can only be a constant
1135 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1136 werror (E_CONST_EXPECTED);
1139 /* insert the symbol into the symbol table */
1140 /* with level = 0 & name = rname */
1141 newSym = copySymbol (sym);
1142 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1144 /* now lift the code to main */
1145 if (IS_AGGREGATE (sym->type))
1146 work = initAggregates (sym, sym->ival, NULL);
1148 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1149 list2expr (sym->ival));
1151 setAstLineno (work, sym->lineDef);
1155 staticAutos = newNode (NULLOP, staticAutos, work);
1162 /* if there is an initial value */
1163 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1165 if (IS_AGGREGATE (sym->type))
1166 work = initAggregates (sym, sym->ival, NULL);
1168 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1169 list2expr (sym->ival));
1171 setAstLineno (work, sym->lineDef);
1174 init = newNode (NULLOP, init, work);
1183 /*-----------------------------------------------------------------*/
1184 /* stringToSymbol - creates a symbol from a literal string */
1185 /*-----------------------------------------------------------------*/
1187 stringToSymbol (value * val)
1189 char name[SDCC_NAME_MAX + 1];
1190 static int charLbl = 0;
1193 sprintf (name, "_str_%d", charLbl++);
1194 sym = newSymbol (name, 0); /* make it @ level 0 */
1195 strcpy (sym->rname, name);
1197 /* copy the type from the value passed */
1198 sym->type = copyLinkChain (val->type);
1199 sym->etype = getSpec (sym->type);
1200 /* change to storage class & output class */
1201 SPEC_SCLS (sym->etype) = S_CODE;
1202 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1203 SPEC_STAT (sym->etype) = 1;
1204 /* make the level & block = 0 */
1205 sym->block = sym->level = 0;
1207 /* create an ival */
1208 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1213 allocVariables (sym);
1216 return symbolVal (sym);
1220 /*-----------------------------------------------------------------*/
1221 /* processBlockVars - will go thru the ast looking for block if */
1222 /* a block is found then will allocate the syms */
1223 /* will also gather the auto inits present */
1224 /*-----------------------------------------------------------------*/
1226 processBlockVars (ast * tree, int *stack, int action)
1231 /* if this is a block */
1232 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1236 if (action == ALLOCATE)
1238 autoInit = gatherAutoInit (tree->values.sym);
1239 *stack += allocVariables (tree->values.sym);
1241 /* if there are auto inits then do them */
1243 tree->left = newNode (NULLOP, autoInit, tree->left);
1245 else /* action is deallocate */
1246 deallocLocal (tree->values.sym);
1249 processBlockVars (tree->left, stack, action);
1250 processBlockVars (tree->right, stack, action);
1254 /*-----------------------------------------------------------------*/
1255 /* constExprValue - returns the value of a constant expression */
1256 /*-----------------------------------------------------------------*/
1258 constExprValue (ast * cexpr, int check)
1260 cexpr = decorateType (resolveSymbols (cexpr));
1262 /* if this is not a constant then */
1263 if (!IS_LITERAL (cexpr->ftype))
1265 /* then check if this is a literal array
1267 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1268 SPEC_CVAL (cexpr->etype).v_char &&
1269 IS_ARRAY (cexpr->ftype))
1271 value *val = valFromType (cexpr->ftype);
1272 SPEC_SCLS (val->etype) = S_LITERAL;
1273 val->sym = cexpr->opval.val->sym;
1274 val->sym->type = copyLinkChain (cexpr->ftype);
1275 val->sym->etype = getSpec (val->sym->type);
1276 strcpy (val->name, cexpr->opval.val->sym->rname);
1280 /* if we are casting a literal value then */
1281 if (IS_AST_OP (cexpr) &&
1282 cexpr->opval.op == CAST &&
1283 IS_LITERAL (cexpr->left->ftype))
1284 return valCastLiteral (cexpr->ftype,
1285 floatFromVal (cexpr->left->opval.val));
1287 if (IS_AST_VALUE (cexpr))
1288 return cexpr->opval.val;
1291 werror (E_CONST_EXPECTED, "found expression");
1296 /* return the value */
1297 return cexpr->opval.val;
1301 /*-----------------------------------------------------------------*/
1302 /* isLabelInAst - will return true if a given label is found */
1303 /*-----------------------------------------------------------------*/
1305 isLabelInAst (symbol * label, ast * tree)
1307 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1310 if (IS_AST_OP (tree) &&
1311 tree->opval.op == LABEL &&
1312 isSymbolEqual (AST_SYMBOL (tree->left), label))
1315 return isLabelInAst (label, tree->right) &&
1316 isLabelInAst (label, tree->left);
1320 /*-----------------------------------------------------------------*/
1321 /* isLoopCountable - return true if the loop count can be determi- */
1322 /* -ned at compile time . */
1323 /*-----------------------------------------------------------------*/
1325 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1326 symbol ** sym, ast ** init, ast ** end)
1329 /* the loop is considered countable if the following
1330 conditions are true :-
1332 a) initExpr :- <sym> = <const>
1333 b) condExpr :- <sym> < <const1>
1334 c) loopExpr :- <sym> ++
1337 /* first check the initExpr */
1338 if (IS_AST_OP (initExpr) &&
1339 initExpr->opval.op == '=' && /* is assignment */
1340 IS_AST_SYM_VALUE (initExpr->left))
1341 { /* left is a symbol */
1343 *sym = AST_SYMBOL (initExpr->left);
1344 *init = initExpr->right;
1349 /* for now the symbol has to be of
1351 if (!IS_INTEGRAL ((*sym)->type))
1354 /* now check condExpr */
1355 if (IS_AST_OP (condExpr))
1358 switch (condExpr->opval.op)
1361 if (IS_AST_SYM_VALUE (condExpr->left) &&
1362 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1363 IS_AST_LIT_VALUE (condExpr->right))
1365 *end = condExpr->right;
1371 if (IS_AST_OP (condExpr->left) &&
1372 condExpr->left->opval.op == '>' &&
1373 IS_AST_LIT_VALUE (condExpr->left->right) &&
1374 IS_AST_SYM_VALUE (condExpr->left->left) &&
1375 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1378 *end = newNode ('+', condExpr->left->right,
1379 newAst_VALUE (constVal ("1")));
1390 /* check loop expression is of the form <sym>++ */
1391 if (!IS_AST_OP (loopExpr))
1394 /* check if <sym> ++ */
1395 if (loopExpr->opval.op == INC_OP)
1401 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1402 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1409 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1410 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1418 if (loopExpr->opval.op == ADD_ASSIGN)
1421 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1422 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1423 IS_AST_LIT_VALUE (loopExpr->right) &&
1424 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1432 /*-----------------------------------------------------------------*/
1433 /* astHasVolatile - returns true if ast contains any volatile */
1434 /*-----------------------------------------------------------------*/
1436 astHasVolatile (ast * tree)
1441 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1444 if (IS_AST_OP (tree))
1445 return astHasVolatile (tree->left) ||
1446 astHasVolatile (tree->right);
1451 /*-----------------------------------------------------------------*/
1452 /* astHasPointer - return true if the ast contains any ptr variable */
1453 /*-----------------------------------------------------------------*/
1455 astHasPointer (ast * tree)
1460 if (IS_AST_LINK (tree))
1463 /* if we hit an array expression then check
1464 only the left side */
1465 if (IS_AST_OP (tree) && tree->opval.op == '[')
1466 return astHasPointer (tree->left);
1468 if (IS_AST_VALUE (tree))
1469 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1471 return astHasPointer (tree->left) ||
1472 astHasPointer (tree->right);
1476 /*-----------------------------------------------------------------*/
1477 /* astHasSymbol - return true if the ast has the given symbol */
1478 /*-----------------------------------------------------------------*/
1480 astHasSymbol (ast * tree, symbol * sym)
1482 if (!tree || IS_AST_LINK (tree))
1485 if (IS_AST_VALUE (tree))
1487 if (IS_AST_SYM_VALUE (tree))
1488 return isSymbolEqual (AST_SYMBOL (tree), sym);
1493 return astHasSymbol (tree->left, sym) ||
1494 astHasSymbol (tree->right, sym);
1497 /*-----------------------------------------------------------------*/
1498 /* astHasDeref - return true if the ast has an indirect access */
1499 /*-----------------------------------------------------------------*/
1501 astHasDeref (ast * tree)
1503 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1506 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1508 return astHasDeref (tree->left) || astHasDeref (tree->right);
1511 /*-----------------------------------------------------------------*/
1512 /* isConformingBody - the loop body has to conform to a set of rules */
1513 /* for the loop to be considered reversible read on for rules */
1514 /*-----------------------------------------------------------------*/
1516 isConformingBody (ast * pbody, symbol * sym, ast * body)
1519 /* we are going to do a pre-order traversal of the
1520 tree && check for the following conditions. (essentially
1521 a set of very shallow tests )
1522 a) the sym passed does not participate in
1523 any arithmetic operation
1524 b) There are no function calls
1525 c) all jumps are within the body
1526 d) address of loop control variable not taken
1527 e) if an assignment has a pointer on the
1528 left hand side make sure right does not have
1529 loop control variable */
1531 /* if we reach the end or a leaf then true */
1532 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1536 /* if anything else is "volatile" */
1537 if (IS_VOLATILE (TETYPE (pbody)))
1540 /* we will walk the body in a pre-order traversal for
1542 switch (pbody->opval.op)
1544 /*------------------------------------------------------------------*/
1546 return isConformingBody (pbody->right, sym, body);
1548 /*------------------------------------------------------------------*/
1553 /*------------------------------------------------------------------*/
1554 case INC_OP: /* incerement operator unary so left only */
1557 /* sure we are not sym is not modified */
1559 IS_AST_SYM_VALUE (pbody->left) &&
1560 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1564 IS_AST_SYM_VALUE (pbody->right) &&
1565 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1570 /*------------------------------------------------------------------*/
1572 case '*': /* can be unary : if right is null then unary operation */
1577 /* if right is NULL then unary operation */
1578 /*------------------------------------------------------------------*/
1579 /*----------------------------*/
1581 /*----------------------------*/
1584 if (IS_AST_SYM_VALUE (pbody->left) &&
1585 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1588 return isConformingBody (pbody->left, sym, body);
1592 if (astHasSymbol (pbody->left, sym) ||
1593 astHasSymbol (pbody->right, sym))
1598 /*------------------------------------------------------------------*/
1606 if (IS_AST_SYM_VALUE (pbody->left) &&
1607 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1610 if (IS_AST_SYM_VALUE (pbody->right) &&
1611 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1614 return isConformingBody (pbody->left, sym, body) &&
1615 isConformingBody (pbody->right, sym, body);
1622 if (IS_AST_SYM_VALUE (pbody->left) &&
1623 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1625 return isConformingBody (pbody->left, sym, body);
1627 /*------------------------------------------------------------------*/
1639 case SIZEOF: /* evaluate wihout code generation */
1641 return isConformingBody (pbody->left, sym, body) &&
1642 isConformingBody (pbody->right, sym, body);
1644 /*------------------------------------------------------------------*/
1647 /* if left has a pointer & right has loop
1648 control variable then we cannot */
1649 if (astHasPointer (pbody->left) &&
1650 astHasSymbol (pbody->right, sym))
1652 if (astHasVolatile (pbody->left))
1655 if (IS_AST_SYM_VALUE (pbody->left) &&
1656 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1659 if (astHasVolatile (pbody->left))
1662 if (astHasDeref(pbody->right)) return FALSE;
1664 return isConformingBody (pbody->left, sym, body) &&
1665 isConformingBody (pbody->right, sym, body);
1676 assert ("Parser should not have generated this\n");
1678 /*------------------------------------------------------------------*/
1679 /*----------------------------*/
1680 /* comma operator */
1681 /*----------------------------*/
1683 return isConformingBody (pbody->left, sym, body) &&
1684 isConformingBody (pbody->right, sym, body);
1686 /*------------------------------------------------------------------*/
1687 /*----------------------------*/
1689 /*----------------------------*/
1693 /*------------------------------------------------------------------*/
1694 /*----------------------------*/
1695 /* return statement */
1696 /*----------------------------*/
1701 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1706 if (astHasSymbol (pbody->left, sym))
1713 return isConformingBody (pbody->left, sym, body) &&
1714 isConformingBody (pbody->right, sym, body);
1720 /*-----------------------------------------------------------------*/
1721 /* isLoopReversible - takes a for loop as input && returns true */
1722 /* if the for loop is reversible. If yes will set the value of */
1723 /* the loop control var & init value & termination value */
1724 /*-----------------------------------------------------------------*/
1726 isLoopReversible (ast * loop, symbol ** loopCntrl,
1727 ast ** init, ast ** end)
1729 /* if option says don't do it then don't */
1730 if (optimize.noLoopReverse)
1732 /* there are several tests to determine this */
1734 /* for loop has to be of the form
1735 for ( <sym> = <const1> ;
1736 [<sym> < <const2>] ;
1737 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1739 if (!isLoopCountable (AST_FOR (loop, initExpr),
1740 AST_FOR (loop, condExpr),
1741 AST_FOR (loop, loopExpr),
1742 loopCntrl, init, end))
1745 /* now do some serious checking on the body of the loop
1748 return isConformingBody (loop->left, *loopCntrl, loop->left);
1752 /*-----------------------------------------------------------------*/
1753 /* replLoopSym - replace the loop sym by loop sym -1 */
1754 /*-----------------------------------------------------------------*/
1756 replLoopSym (ast * body, symbol * sym)
1759 if (!body || IS_AST_LINK (body))
1762 if (IS_AST_SYM_VALUE (body))
1765 if (isSymbolEqual (AST_SYMBOL (body), sym))
1769 body->opval.op = '-';
1770 body->left = newAst_VALUE (symbolVal (sym));
1771 body->right = newAst_VALUE (constVal ("1"));
1779 replLoopSym (body->left, sym);
1780 replLoopSym (body->right, sym);
1784 /*-----------------------------------------------------------------*/
1785 /* reverseLoop - do the actual loop reversal */
1786 /*-----------------------------------------------------------------*/
1788 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1792 /* create the following tree
1797 if (sym) goto for_continue ;
1800 /* put it together piece by piece */
1801 rloop = newNode (NULLOP,
1802 createIf (newAst_VALUE (symbolVal (sym)),
1804 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1807 newAst_VALUE (symbolVal (sym)),
1810 replLoopSym (loop->left, sym);
1812 rloop = newNode (NULLOP,
1814 newAst_VALUE (symbolVal (sym)),
1815 newNode ('-', end, init)),
1816 createLabel (AST_FOR (loop, continueLabel),
1820 newNode (SUB_ASSIGN,
1821 newAst_VALUE (symbolVal (sym)),
1822 newAst_VALUE (constVal ("1"))),
1825 return decorateType (rloop);
1829 //#define DEMAND_INTEGER_PROMOTION
1831 #ifdef DEMAND_INTEGER_PROMOTION
1833 /*-----------------------------------------------------------------*/
1834 /* walk a tree looking for the leaves. Add a typecast to the given */
1835 /* type to each value leaf node. */
1836 /*-----------------------------------------------------------------*/
1838 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1840 if (!node || IS_CALLOP(node))
1842 /* WTF? We should never get here. */
1846 if (!node->left && !node->right)
1848 /* We're at a leaf; if it's a value, apply the typecast */
1849 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1851 *parentPtr = decorateType (newNode (CAST,
1852 newAst_LINK (copyLinkChain (type)),
1860 pushTypeCastToLeaves (type, node->left, &(node->left));
1864 pushTypeCastToLeaves (type, node->right, &(node->right));
1871 /*-----------------------------------------------------------------*/
1872 /* Given an assignment operation in a tree, determine if the LHS */
1873 /* (the result) has a different (integer) type than the RHS. */
1874 /* If so, walk the RHS and add a typecast to the type of the LHS */
1875 /* to all leaf nodes. */
1876 /*-----------------------------------------------------------------*/
1878 propAsgType (ast * tree)
1880 #ifdef DEMAND_INTEGER_PROMOTION
1881 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1883 /* Nothing to do here... */
1887 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1889 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1896 /*-----------------------------------------------------------------*/
1897 /* decorateType - compute type for this tree also does type cheking */
1898 /* this is done bottom up, since type have to flow upwards */
1899 /* it also does constant folding, and paramater checking */
1900 /*-----------------------------------------------------------------*/
1902 decorateType (ast * tree)
1910 /* if already has type then do nothing */
1911 if (tree->decorated)
1914 tree->decorated = 1;
1916 /* print the line */
1917 /* if not block & function */
1918 if (tree->type == EX_OP &&
1919 (tree->opval.op != FUNCTION &&
1920 tree->opval.op != BLOCK &&
1921 tree->opval.op != NULLOP))
1923 filename = tree->filename;
1924 lineno = tree->lineno;
1927 /* if any child is an error | this one is an error do nothing */
1928 if (tree->isError ||
1929 (tree->left && tree->left->isError) ||
1930 (tree->right && tree->right->isError))
1933 /*------------------------------------------------------------------*/
1934 /*----------------------------*/
1935 /* leaf has been reached */
1936 /*----------------------------*/
1937 /* if this is of type value */
1938 /* just get the type */
1939 if (tree->type == EX_VALUE)
1942 if (IS_LITERAL (tree->opval.val->etype))
1945 /* if this is a character array then declare it */
1946 if (IS_ARRAY (tree->opval.val->type))
1947 tree->opval.val = stringToSymbol (tree->opval.val);
1949 /* otherwise just copy the type information */
1950 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1951 if (funcInChain (tree->opval.val->type))
1953 tree->hasVargs = tree->opval.val->sym->hasVargs;
1954 tree->args = copyValueChain (tree->opval.val->sym->args);
1959 if (tree->opval.val->sym)
1961 /* if the undefined flag is set then give error message */
1962 if (tree->opval.val->sym->undefined)
1964 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1966 TTYPE (tree) = TETYPE (tree) =
1967 tree->opval.val->type = tree->opval.val->sym->type =
1968 tree->opval.val->etype = tree->opval.val->sym->etype =
1969 copyLinkChain (INTTYPE);
1974 /* if impilicit i.e. struct/union member then no type */
1975 if (tree->opval.val->sym->implicit)
1976 TTYPE (tree) = TETYPE (tree) = NULL;
1981 /* else copy the type */
1982 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1984 /* and mark it as referenced */
1985 tree->opval.val->sym->isref = 1;
1986 /* if this is of type function or function pointer */
1987 if (funcInChain (tree->opval.val->type))
1989 tree->hasVargs = tree->opval.val->sym->hasVargs;
1990 tree->args = copyValueChain (tree->opval.val->sym->args);
2000 /* if type link for the case of cast */
2001 if (tree->type == EX_LINK)
2003 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2010 dtl = decorateType (tree->left);
2011 dtr = decorateType (tree->right);
2013 /* this is to take care of situations
2014 when the tree gets rewritten */
2015 if (dtl != tree->left)
2017 if (dtr != tree->right)
2021 /* depending on type of operator do */
2023 switch (tree->opval.op)
2025 /*------------------------------------------------------------------*/
2026 /*----------------------------*/
2028 /*----------------------------*/
2031 /* determine which is the array & which the index */
2032 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2035 ast *tempTree = tree->left;
2036 tree->left = tree->right;
2037 tree->right = tempTree;
2040 /* first check if this is a array or a pointer */
2041 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2043 werror (E_NEED_ARRAY_PTR, "[]");
2044 goto errorTreeReturn;
2047 /* check if the type of the idx */
2048 if (!IS_INTEGRAL (RTYPE (tree)))
2050 werror (E_IDX_NOT_INT);
2051 goto errorTreeReturn;
2054 /* if the left is an rvalue then error */
2057 werror (E_LVALUE_REQUIRED, "array access");
2058 goto errorTreeReturn;
2061 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2062 if (IS_PTR(LTYPE(tree))) {
2063 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2067 /*------------------------------------------------------------------*/
2068 /*----------------------------*/
2070 /*----------------------------*/
2072 /* if this is not a structure */
2073 if (!IS_STRUCT (LTYPE (tree)))
2075 werror (E_STRUCT_UNION, ".");
2076 goto errorTreeReturn;
2078 TTYPE (tree) = structElemType (LTYPE (tree),
2079 (tree->right->type == EX_VALUE ?
2080 tree->right->opval.val : NULL), &tree->args);
2081 TETYPE (tree) = getSpec (TTYPE (tree));
2084 /*------------------------------------------------------------------*/
2085 /*----------------------------*/
2086 /* struct/union pointer */
2087 /*----------------------------*/
2089 /* if not pointer to a structure */
2090 if (!IS_PTR (LTYPE (tree)))
2092 werror (E_PTR_REQD);
2093 goto errorTreeReturn;
2096 if (!IS_STRUCT (LTYPE (tree)->next))
2098 werror (E_STRUCT_UNION, "->");
2099 goto errorTreeReturn;
2102 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2103 (tree->right->type == EX_VALUE ?
2104 tree->right->opval.val : NULL), &tree->args);
2105 TETYPE (tree) = getSpec (TTYPE (tree));
2108 /*------------------------------------------------------------------*/
2109 /*----------------------------*/
2110 /* ++/-- operation */
2111 /*----------------------------*/
2112 case INC_OP: /* incerement operator unary so left only */
2115 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2116 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2117 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
2118 werror (E_CODE_WRITE, "++/--");
2127 /*------------------------------------------------------------------*/
2128 /*----------------------------*/
2130 /*----------------------------*/
2131 case '&': /* can be unary */
2132 /* if right is NULL then unary operation */
2133 if (tree->right) /* not an unary operation */
2136 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2138 werror (E_BITWISE_OP);
2139 werror (E_CONTINUE, "left & right types are ");
2140 printTypeChain (LTYPE (tree), stderr);
2141 fprintf (stderr, ",");
2142 printTypeChain (RTYPE (tree), stderr);
2143 fprintf (stderr, "\n");
2144 goto errorTreeReturn;
2147 /* if they are both literal */
2148 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2150 tree->type = EX_VALUE;
2151 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2152 valFromType (RETYPE (tree)), '&');
2154 tree->right = tree->left = NULL;
2155 TETYPE (tree) = tree->opval.val->etype;
2156 TTYPE (tree) = tree->opval.val->type;
2160 /* see if this is a GETHBIT operation if yes
2163 ast *otree = optimizeGetHbit (tree);
2166 return decorateType (otree);
2170 // we can't do this because of "(int & 0xff) << 3"
2172 /* if right or left is literal then result of that type */
2173 if (IS_LITERAL (RTYPE (tree)))
2176 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2177 TETYPE (tree) = getSpec (TTYPE (tree));
2178 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2182 if (IS_LITERAL (LTYPE (tree)))
2184 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2185 TETYPE (tree) = getSpec (TTYPE (tree));
2186 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2192 computeType (LTYPE (tree), RTYPE (tree));
2193 TETYPE (tree) = getSpec (TTYPE (tree));
2198 computeType (LTYPE (tree), RTYPE (tree));
2199 TETYPE (tree) = getSpec (TTYPE (tree));
2201 LRVAL (tree) = RRVAL (tree) = 1;
2205 /*------------------------------------------------------------------*/
2206 /*----------------------------*/
2208 /*----------------------------*/
2210 p->class = DECLARATOR;
2211 /* if bit field then error */
2212 if (IS_BITVAR (tree->left->etype))
2214 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2215 goto errorTreeReturn;
2218 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2220 werror (E_ILLEGAL_ADDR, "address of register variable");
2221 goto errorTreeReturn;
2224 if (IS_FUNC (LTYPE (tree)))
2226 werror (E_ILLEGAL_ADDR, "address of function");
2227 goto errorTreeReturn;
2232 werror (E_LVALUE_REQUIRED, "address of");
2233 goto errorTreeReturn;
2235 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2237 DCL_TYPE (p) = CPOINTER;
2238 DCL_PTR_CONST (p) = port->mem.code_ro;
2240 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2241 DCL_TYPE (p) = FPOINTER;
2242 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2243 DCL_TYPE (p) = PPOINTER;
2244 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2245 DCL_TYPE (p) = IPOINTER;
2246 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2247 DCL_TYPE (p) = EEPPOINTER;
2249 DCL_TYPE (p) = POINTER;
2251 if (IS_AST_SYM_VALUE (tree->left))
2253 AST_SYMBOL (tree->left)->addrtaken = 1;
2254 AST_SYMBOL (tree->left)->allocreq = 1;
2257 p->next = LTYPE (tree);
2259 TETYPE (tree) = getSpec (TTYPE (tree));
2260 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2261 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2266 /*------------------------------------------------------------------*/
2267 /*----------------------------*/
2269 /*----------------------------*/
2271 /* if the rewrite succeeds then don't go any furthur */
2273 ast *wtree = optimizeRRCRLC (tree);
2275 return decorateType (wtree);
2277 /*------------------------------------------------------------------*/
2278 /*----------------------------*/
2280 /*----------------------------*/
2282 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2284 werror (E_BITWISE_OP);
2285 werror (E_CONTINUE, "left & right types are ");
2286 printTypeChain (LTYPE (tree), stderr);
2287 fprintf (stderr, ",");
2288 printTypeChain (RTYPE (tree), stderr);
2289 fprintf (stderr, "\n");
2290 goto errorTreeReturn;
2293 /* if they are both literal then */
2294 /* rewrite the tree */
2295 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2297 tree->type = EX_VALUE;
2298 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2299 valFromType (RETYPE (tree)),
2301 tree->right = tree->left = NULL;
2302 TETYPE (tree) = tree->opval.val->etype;
2303 TTYPE (tree) = tree->opval.val->type;
2306 LRVAL (tree) = RRVAL (tree) = 1;
2307 TETYPE (tree) = getSpec (TTYPE (tree) =
2308 computeType (LTYPE (tree),
2311 /*------------------------------------------------------------------*/
2312 /*----------------------------*/
2314 /*----------------------------*/
2316 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2318 werror (E_INVALID_OP, "divide");
2319 goto errorTreeReturn;
2321 /* if they are both literal then */
2322 /* rewrite the tree */
2323 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2325 tree->type = EX_VALUE;
2326 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2327 valFromType (RETYPE (tree)));
2328 tree->right = tree->left = NULL;
2329 TETYPE (tree) = getSpec (TTYPE (tree) =
2330 tree->opval.val->type);
2333 LRVAL (tree) = RRVAL (tree) = 1;
2334 TETYPE (tree) = getSpec (TTYPE (tree) =
2335 computeType (LTYPE (tree),
2339 /*------------------------------------------------------------------*/
2340 /*----------------------------*/
2342 /*----------------------------*/
2344 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2346 werror (E_BITWISE_OP);
2347 werror (E_CONTINUE, "left & right types are ");
2348 printTypeChain (LTYPE (tree), stderr);
2349 fprintf (stderr, ",");
2350 printTypeChain (RTYPE (tree), stderr);
2351 fprintf (stderr, "\n");
2352 goto errorTreeReturn;
2354 /* if they are both literal then */
2355 /* rewrite the tree */
2356 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2358 tree->type = EX_VALUE;
2359 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2360 valFromType (RETYPE (tree)));
2361 tree->right = tree->left = NULL;
2362 TETYPE (tree) = getSpec (TTYPE (tree) =
2363 tree->opval.val->type);
2366 LRVAL (tree) = RRVAL (tree) = 1;
2367 TETYPE (tree) = getSpec (TTYPE (tree) =
2368 computeType (LTYPE (tree),
2372 /*------------------------------------------------------------------*/
2373 /*----------------------------*/
2374 /* address dereference */
2375 /*----------------------------*/
2376 case '*': /* can be unary : if right is null then unary operation */
2379 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2381 werror (E_PTR_REQD);
2382 goto errorTreeReturn;
2387 werror (E_LVALUE_REQUIRED, "pointer deref");
2388 goto errorTreeReturn;
2390 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2391 LTYPE (tree)->next : NULL);
2392 TETYPE (tree) = getSpec (TTYPE (tree));
2393 tree->args = tree->left->args;
2394 tree->hasVargs = tree->left->hasVargs;
2395 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2399 /*------------------------------------------------------------------*/
2400 /*----------------------------*/
2401 /* multiplication */
2402 /*----------------------------*/
2403 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2405 werror (E_INVALID_OP, "multiplication");
2406 goto errorTreeReturn;
2409 /* if they are both literal then */
2410 /* rewrite the tree */
2411 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2413 tree->type = EX_VALUE;
2414 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2415 valFromType (RETYPE (tree)));
2416 tree->right = tree->left = NULL;
2417 TETYPE (tree) = getSpec (TTYPE (tree) =
2418 tree->opval.val->type);
2422 /* if left is a literal exchange left & right */
2423 if (IS_LITERAL (LTYPE (tree)))
2425 ast *tTree = tree->left;
2426 tree->left = tree->right;
2427 tree->right = tTree;
2430 LRVAL (tree) = RRVAL (tree) = 1;
2431 /* promote result to int if left & right are char
2432 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2433 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2434 TETYPE (tree) = getSpec (TTYPE (tree) =
2435 computeType (LTYPE (tree),
2437 SPEC_NOUN(TETYPE(tree)) = V_INT;
2439 TETYPE (tree) = getSpec (TTYPE (tree) =
2440 computeType (LTYPE (tree),
2445 /*------------------------------------------------------------------*/
2446 /*----------------------------*/
2447 /* unary '+' operator */
2448 /*----------------------------*/
2453 if (!IS_INTEGRAL (LTYPE (tree)))
2455 werror (E_UNARY_OP, '+');
2456 goto errorTreeReturn;
2459 /* if left is a literal then do it */
2460 if (IS_LITERAL (LTYPE (tree)))
2462 tree->type = EX_VALUE;
2463 tree->opval.val = valFromType (LETYPE (tree));
2465 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2469 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2473 /*------------------------------------------------------------------*/
2474 /*----------------------------*/
2476 /*----------------------------*/
2478 /* this is not a unary operation */
2479 /* if both pointers then problem */
2480 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2481 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2483 werror (E_PTR_PLUS_PTR);
2484 goto errorTreeReturn;
2487 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2488 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2490 werror (E_PLUS_INVALID, "+");
2491 goto errorTreeReturn;
2494 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2495 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2497 werror (E_PLUS_INVALID, "+");
2498 goto errorTreeReturn;
2500 /* if they are both literal then */
2501 /* rewrite the tree */
2502 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2504 tree->type = EX_VALUE;
2505 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2506 valFromType (RETYPE (tree)));
2507 tree->right = tree->left = NULL;
2508 TETYPE (tree) = getSpec (TTYPE (tree) =
2509 tree->opval.val->type);
2513 /* if the right is a pointer or left is a literal
2514 xchange left & right */
2515 if (IS_ARRAY (RTYPE (tree)) ||
2516 IS_PTR (RTYPE (tree)) ||
2517 IS_LITERAL (LTYPE (tree)))
2519 ast *tTree = tree->left;
2520 tree->left = tree->right;
2521 tree->right = tTree;
2524 LRVAL (tree) = RRVAL (tree) = 1;
2525 /* if the left is a pointer */
2526 if (IS_PTR (LTYPE (tree)))
2527 TETYPE (tree) = getSpec (TTYPE (tree) =
2530 TETYPE (tree) = getSpec (TTYPE (tree) =
2531 computeType (LTYPE (tree),
2535 /*------------------------------------------------------------------*/
2536 /*----------------------------*/
2538 /*----------------------------*/
2539 case '-': /* can be unary */
2540 /* if right is null then unary */
2544 if (!IS_ARITHMETIC (LTYPE (tree)))
2546 werror (E_UNARY_OP, tree->opval.op);
2547 goto errorTreeReturn;
2550 /* if left is a literal then do it */
2551 if (IS_LITERAL (LTYPE (tree)))
2553 tree->type = EX_VALUE;
2554 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2556 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2557 SPEC_USIGN(TETYPE(tree)) = 0;
2561 TTYPE (tree) = LTYPE (tree);
2565 /*------------------------------------------------------------------*/
2566 /*----------------------------*/
2568 /*----------------------------*/
2570 if (!(IS_PTR (LTYPE (tree)) ||
2571 IS_ARRAY (LTYPE (tree)) ||
2572 IS_ARITHMETIC (LTYPE (tree))))
2574 werror (E_PLUS_INVALID, "-");
2575 goto errorTreeReturn;
2578 if (!(IS_PTR (RTYPE (tree)) ||
2579 IS_ARRAY (RTYPE (tree)) ||
2580 IS_ARITHMETIC (RTYPE (tree))))
2582 werror (E_PLUS_INVALID, "-");
2583 goto errorTreeReturn;
2586 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2587 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2588 IS_INTEGRAL (RTYPE (tree))))
2590 werror (E_PLUS_INVALID, "-");
2591 goto errorTreeReturn;
2594 /* if they are both literal then */
2595 /* rewrite the tree */
2596 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2598 tree->type = EX_VALUE;
2599 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2600 valFromType (RETYPE (tree)));
2601 tree->right = tree->left = NULL;
2602 TETYPE (tree) = getSpec (TTYPE (tree) =
2603 tree->opval.val->type);
2607 /* if the left & right are equal then zero */
2608 if (isAstEqual (tree->left, tree->right))
2610 tree->type = EX_VALUE;
2611 tree->left = tree->right = NULL;
2612 tree->opval.val = constVal ("0");
2613 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2617 /* if both of them are pointers or arrays then */
2618 /* the result is going to be an integer */
2619 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2620 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2621 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2623 /* if only the left is a pointer */
2624 /* then result is a pointer */
2625 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2626 TETYPE (tree) = getSpec (TTYPE (tree) =
2629 TETYPE (tree) = getSpec (TTYPE (tree) =
2630 computeType (LTYPE (tree),
2632 LRVAL (tree) = RRVAL (tree) = 1;
2635 /*------------------------------------------------------------------*/
2636 /*----------------------------*/
2638 /*----------------------------*/
2640 /* can be only integral type */
2641 if (!IS_INTEGRAL (LTYPE (tree)))
2643 werror (E_UNARY_OP, tree->opval.op);
2644 goto errorTreeReturn;
2647 /* if left is a literal then do it */
2648 if (IS_LITERAL (LTYPE (tree)))
2650 tree->type = EX_VALUE;
2651 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2653 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2657 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2660 /*------------------------------------------------------------------*/
2661 /*----------------------------*/
2663 /*----------------------------*/
2665 /* can be pointer */
2666 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2667 !IS_PTR (LTYPE (tree)) &&
2668 !IS_ARRAY (LTYPE (tree)))
2670 werror (E_UNARY_OP, tree->opval.op);
2671 goto errorTreeReturn;
2674 /* if left is a literal then do it */
2675 if (IS_LITERAL (LTYPE (tree)))
2677 tree->type = EX_VALUE;
2678 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2680 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2684 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2687 /*------------------------------------------------------------------*/
2688 /*----------------------------*/
2690 /*----------------------------*/
2693 TTYPE (tree) = LTYPE (tree);
2694 TETYPE (tree) = LETYPE (tree);
2698 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2703 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2705 werror (E_SHIFT_OP_INVALID);
2706 werror (E_CONTINUE, "left & right types are ");
2707 printTypeChain (LTYPE (tree), stderr);
2708 fprintf (stderr, ",");
2709 printTypeChain (RTYPE (tree), stderr);
2710 fprintf (stderr, "\n");
2711 goto errorTreeReturn;
2714 /* if they are both literal then */
2715 /* rewrite the tree */
2716 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2718 tree->type = EX_VALUE;
2719 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2720 valFromType (RETYPE (tree)),
2721 (tree->opval.op == LEFT_OP ? 1 : 0));
2722 tree->right = tree->left = NULL;
2723 TETYPE (tree) = getSpec (TTYPE (tree) =
2724 tree->opval.val->type);
2727 /* if only the right side is a literal & we are
2728 shifting more than size of the left operand then zero */
2729 if (IS_LITERAL (RTYPE (tree)) &&
2730 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2731 (getSize (LTYPE (tree)) * 8))
2733 werror (W_SHIFT_CHANGED,
2734 (tree->opval.op == LEFT_OP ? "left" : "right"));
2735 tree->type = EX_VALUE;
2736 tree->left = tree->right = NULL;
2737 tree->opval.val = constVal ("0");
2738 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2741 LRVAL (tree) = RRVAL (tree) = 1;
2742 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2744 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2748 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2752 /*------------------------------------------------------------------*/
2753 /*----------------------------*/
2755 /*----------------------------*/
2756 case CAST: /* change the type */
2757 /* cannot cast to an aggregate type */
2758 if (IS_AGGREGATE (LTYPE (tree)))
2760 werror (E_CAST_ILLEGAL);
2761 goto errorTreeReturn;
2764 /* make sure the type is complete and sane */
2765 checkTypeSanity(LETYPE(tree), "(cast)");
2767 /* if the right is a literal replace the tree */
2768 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2770 tree->type = EX_VALUE;
2772 valCastLiteral (LTYPE (tree),
2773 floatFromVal (valFromType (RETYPE (tree))));
2776 TTYPE (tree) = tree->opval.val->type;
2777 tree->values.literalFromCast = 1;
2781 TTYPE (tree) = LTYPE (tree);
2785 TETYPE (tree) = getSpec (TTYPE (tree));
2789 /*------------------------------------------------------------------*/
2790 /*----------------------------*/
2791 /* logical &&, || */
2792 /*----------------------------*/
2795 /* each must me arithmetic type or be a pointer */
2796 if (!IS_PTR (LTYPE (tree)) &&
2797 !IS_ARRAY (LTYPE (tree)) &&
2798 !IS_INTEGRAL (LTYPE (tree)))
2800 werror (E_COMPARE_OP);
2801 goto errorTreeReturn;
2804 if (!IS_PTR (RTYPE (tree)) &&
2805 !IS_ARRAY (RTYPE (tree)) &&
2806 !IS_INTEGRAL (RTYPE (tree)))
2808 werror (E_COMPARE_OP);
2809 goto errorTreeReturn;
2811 /* if they are both literal then */
2812 /* rewrite the tree */
2813 if (IS_LITERAL (RTYPE (tree)) &&
2814 IS_LITERAL (LTYPE (tree)))
2816 tree->type = EX_VALUE;
2817 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2818 valFromType (RETYPE (tree)),
2820 tree->right = tree->left = NULL;
2821 TETYPE (tree) = getSpec (TTYPE (tree) =
2822 tree->opval.val->type);
2825 LRVAL (tree) = RRVAL (tree) = 1;
2826 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2829 /*------------------------------------------------------------------*/
2830 /*----------------------------*/
2831 /* comparison operators */
2832 /*----------------------------*/
2840 ast *lt = optimizeCompare (tree);
2846 /* if they are pointers they must be castable */
2847 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2849 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2851 werror (E_COMPARE_OP);
2852 fprintf (stderr, "comparing type ");
2853 printTypeChain (LTYPE (tree), stderr);
2854 fprintf (stderr, "to type ");
2855 printTypeChain (RTYPE (tree), stderr);
2856 fprintf (stderr, "\n");
2857 goto errorTreeReturn;
2860 /* else they should be promotable to one another */
2863 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2864 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2866 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2868 werror (E_COMPARE_OP);
2869 fprintf (stderr, "comparing type ");
2870 printTypeChain (LTYPE (tree), stderr);
2871 fprintf (stderr, "to type ");
2872 printTypeChain (RTYPE (tree), stderr);
2873 fprintf (stderr, "\n");
2874 goto errorTreeReturn;
2878 /* if they are both literal then */
2879 /* rewrite the tree */
2880 if (IS_LITERAL (RTYPE (tree)) &&
2881 IS_LITERAL (LTYPE (tree)))
2883 tree->type = EX_VALUE;
2884 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2885 valFromType (RETYPE (tree)),
2887 tree->right = tree->left = NULL;
2888 TETYPE (tree) = getSpec (TTYPE (tree) =
2889 tree->opval.val->type);
2892 LRVAL (tree) = RRVAL (tree) = 1;
2893 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2896 /*------------------------------------------------------------------*/
2897 /*----------------------------*/
2899 /*----------------------------*/
2900 case SIZEOF: /* evaluate wihout code generation */
2901 /* change the type to a integer */
2902 tree->type = EX_VALUE;
2903 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2904 tree->opval.val = constVal (buffer);
2905 tree->right = tree->left = NULL;
2906 TETYPE (tree) = getSpec (TTYPE (tree) =
2907 tree->opval.val->type);
2910 /*------------------------------------------------------------------*/
2911 /*----------------------------*/
2912 /* conditional operator '?' */
2913 /*----------------------------*/
2915 /* the type is value of the colon operator (on the right) */
2916 assert(IS_COLON_OP(tree->right));
2917 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2918 TETYPE (tree) = getSpec (TTYPE (tree));
2922 /* if they don't match we have a problem */
2923 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2925 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2926 goto errorTreeReturn;
2929 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2930 TETYPE (tree) = getSpec (TTYPE (tree));
2934 /*------------------------------------------------------------------*/
2935 /*----------------------------*/
2936 /* assignment operators */
2937 /*----------------------------*/
2940 /* for these it must be both must be integral */
2941 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2942 !IS_ARITHMETIC (RTYPE (tree)))
2944 werror (E_OPS_INTEGRAL);
2945 goto errorTreeReturn;
2948 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2950 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2951 werror (E_CODE_WRITE, " ");
2955 werror (E_LVALUE_REQUIRED, "*= or /=");
2956 goto errorTreeReturn;
2969 /* for these it must be both must be integral */
2970 if (!IS_INTEGRAL (LTYPE (tree)) ||
2971 !IS_INTEGRAL (RTYPE (tree)))
2973 werror (E_OPS_INTEGRAL);
2974 goto errorTreeReturn;
2977 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2979 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2980 werror (E_CODE_WRITE, " ");
2984 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2985 goto errorTreeReturn;
2993 /*------------------------------------------------------------------*/
2994 /*----------------------------*/
2996 /*----------------------------*/
2998 if (!(IS_PTR (LTYPE (tree)) ||
2999 IS_ARITHMETIC (LTYPE (tree))))
3001 werror (E_PLUS_INVALID, "-=");
3002 goto errorTreeReturn;
3005 if (!(IS_PTR (RTYPE (tree)) ||
3006 IS_ARITHMETIC (RTYPE (tree))))
3008 werror (E_PLUS_INVALID, "-=");
3009 goto errorTreeReturn;
3012 TETYPE (tree) = getSpec (TTYPE (tree) =
3013 computeType (LTYPE (tree),
3016 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3017 werror (E_CODE_WRITE, " ");
3021 werror (E_LVALUE_REQUIRED, "-=");
3022 goto errorTreeReturn;
3030 /*------------------------------------------------------------------*/
3031 /*----------------------------*/
3033 /*----------------------------*/
3035 /* this is not a unary operation */
3036 /* if both pointers then problem */
3037 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3039 werror (E_PTR_PLUS_PTR);
3040 goto errorTreeReturn;
3043 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3045 werror (E_PLUS_INVALID, "+=");
3046 goto errorTreeReturn;
3049 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3051 werror (E_PLUS_INVALID, "+=");
3052 goto errorTreeReturn;
3055 TETYPE (tree) = getSpec (TTYPE (tree) =
3056 computeType (LTYPE (tree),
3059 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3060 werror (E_CODE_WRITE, " ");
3064 werror (E_LVALUE_REQUIRED, "+=");
3065 goto errorTreeReturn;
3068 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3069 tree->opval.op = '=';
3075 /*------------------------------------------------------------------*/
3076 /*----------------------------*/
3077 /* straight assignemnt */
3078 /*----------------------------*/
3080 /* cannot be an aggregate */
3081 if (IS_AGGREGATE (LTYPE (tree)))
3083 werror (E_AGGR_ASSIGN);
3084 goto errorTreeReturn;
3087 /* they should either match or be castable */
3088 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3090 werror (E_TYPE_MISMATCH, "assignment", " ");
3091 fprintf (stderr, "type --> '");
3092 printTypeChain (RTYPE (tree), stderr);
3093 fprintf (stderr, "' ");
3094 fprintf (stderr, "assigned to type --> '");
3095 printTypeChain (LTYPE (tree), stderr);
3096 fprintf (stderr, "'\n");
3097 goto errorTreeReturn;
3100 /* if the left side of the tree is of type void
3101 then report error */
3102 if (IS_VOID (LTYPE (tree)))
3104 werror (E_CAST_ZERO);
3105 fprintf (stderr, "type --> '");
3106 printTypeChain (RTYPE (tree), stderr);
3107 fprintf (stderr, "' ");
3108 fprintf (stderr, "assigned to type --> '");
3109 printTypeChain (LTYPE (tree), stderr);
3110 fprintf (stderr, "'\n");
3113 /* extra checks for pointer types */
3114 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
3115 !IS_GENPTR (LTYPE (tree)))
3117 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
3118 werror (W_PTR_ASSIGN);
3121 TETYPE (tree) = getSpec (TTYPE (tree) =
3125 if (!tree->initMode ) {
3126 if (IS_CONSTANT (LETYPE (tree))) {
3127 werror (E_CODE_WRITE, " ");
3132 werror (E_LVALUE_REQUIRED, "=");
3133 goto errorTreeReturn;
3140 /*------------------------------------------------------------------*/
3141 /*----------------------------*/
3142 /* comma operator */
3143 /*----------------------------*/
3145 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3148 /*------------------------------------------------------------------*/
3149 /*----------------------------*/
3151 /*----------------------------*/
3155 if (processParms (tree->left,
3157 tree->right, &parmNumber, TRUE))
3158 goto errorTreeReturn;
3160 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3162 tree->left->args = reverseVal (tree->left->args);
3163 reverseParms (tree->right);
3166 tree->args = tree->left->args;
3167 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3170 /*------------------------------------------------------------------*/
3171 /*----------------------------*/
3172 /* return statement */
3173 /*----------------------------*/
3178 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3180 werror (E_RETURN_MISMATCH);
3181 goto errorTreeReturn;
3184 if (IS_VOID (currFunc->type->next)
3186 !IS_VOID (RTYPE (tree)))
3188 werror (E_FUNC_VOID);
3189 goto errorTreeReturn;
3192 /* if there is going to be a casing required then add it */
3193 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3195 #if 0 && defined DEMAND_INTEGER_PROMOTION
3196 if (IS_INTEGRAL (currFunc->type->next))
3198 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3204 decorateType (newNode (CAST,
3205 newAst_LINK (copyLinkChain (currFunc->type->next)),
3215 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3217 werror (E_VOID_FUNC, currFunc->name);
3218 goto errorTreeReturn;
3221 TTYPE (tree) = TETYPE (tree) = NULL;
3224 /*------------------------------------------------------------------*/
3225 /*----------------------------*/
3226 /* switch statement */
3227 /*----------------------------*/
3229 /* the switch value must be an integer */
3230 if (!IS_INTEGRAL (LTYPE (tree)))
3232 werror (E_SWITCH_NON_INTEGER);
3233 goto errorTreeReturn;
3236 TTYPE (tree) = TETYPE (tree) = NULL;
3239 /*------------------------------------------------------------------*/
3240 /*----------------------------*/
3242 /*----------------------------*/
3244 tree->left = backPatchLabels (tree->left,
3247 TTYPE (tree) = TETYPE (tree) = NULL;
3250 /*------------------------------------------------------------------*/
3251 /*----------------------------*/
3253 /*----------------------------*/
3256 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3257 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3258 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3260 /* if the for loop is reversible then
3261 reverse it otherwise do what we normally
3267 if (isLoopReversible (tree, &sym, &init, &end))
3268 return reverseLoop (tree, sym, init, end);
3270 return decorateType (createFor (AST_FOR (tree, trueLabel),
3271 AST_FOR (tree, continueLabel),
3272 AST_FOR (tree, falseLabel),
3273 AST_FOR (tree, condLabel),
3274 AST_FOR (tree, initExpr),
3275 AST_FOR (tree, condExpr),
3276 AST_FOR (tree, loopExpr),
3280 TTYPE (tree) = TETYPE (tree) = NULL;
3284 /* some error found this tree will be killed */
3286 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3287 tree->opval.op = NULLOP;
3293 /*-----------------------------------------------------------------*/
3294 /* sizeofOp - processes size of operation */
3295 /*-----------------------------------------------------------------*/
3297 sizeofOp (sym_link * type)
3301 /* make sure the type is complete and sane */
3302 checkTypeSanity(type, "(sizeof)");
3304 /* get the size and convert it to character */
3305 sprintf (buff, "%d", getSize (type));
3307 /* now convert into value */
3308 return constVal (buff);
3312 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3313 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3314 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3315 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3316 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3317 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3318 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3320 /*-----------------------------------------------------------------*/
3321 /* backPatchLabels - change and or not operators to flow control */
3322 /*-----------------------------------------------------------------*/
3324 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3330 if (!(IS_ANDORNOT (tree)))
3333 /* if this an and */
3336 static int localLbl = 0;
3339 sprintf (buffer, "_and_%d", localLbl++);
3340 localLabel = newSymbol (buffer, NestLevel);
3342 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3344 /* if left is already a IFX then just change the if true label in that */
3345 if (!IS_IFX (tree->left))
3346 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3348 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3349 /* right is a IFX then just join */
3350 if (IS_IFX (tree->right))
3351 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3353 tree->right = createLabel (localLabel, tree->right);
3354 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3356 return newNode (NULLOP, tree->left, tree->right);
3359 /* if this is an or operation */
3362 static int localLbl = 0;
3365 sprintf (buffer, "_or_%d", localLbl++);
3366 localLabel = newSymbol (buffer, NestLevel);
3368 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3370 /* if left is already a IFX then just change the if true label in that */
3371 if (!IS_IFX (tree->left))
3372 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3374 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3375 /* right is a IFX then just join */
3376 if (IS_IFX (tree->right))
3377 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3379 tree->right = createLabel (localLabel, tree->right);
3380 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3382 return newNode (NULLOP, tree->left, tree->right);
3388 int wasnot = IS_NOT (tree->left);
3389 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3391 /* if the left is already a IFX */
3392 if (!IS_IFX (tree->left))
3393 tree->left = newNode (IFX, tree->left, NULL);
3397 tree->left->trueLabel = trueLabel;
3398 tree->left->falseLabel = falseLabel;
3402 tree->left->trueLabel = falseLabel;
3403 tree->left->falseLabel = trueLabel;
3410 tree->trueLabel = trueLabel;
3411 tree->falseLabel = falseLabel;
3418 /*-----------------------------------------------------------------*/
3419 /* createBlock - create expression tree for block */
3420 /*-----------------------------------------------------------------*/
3422 createBlock (symbol * decl, ast * body)
3426 /* if the block has nothing */
3430 ex = newNode (BLOCK, NULL, body);
3431 ex->values.sym = decl;
3433 ex->right = ex->right;
3439 /*-----------------------------------------------------------------*/
3440 /* createLabel - creates the expression tree for labels */
3441 /*-----------------------------------------------------------------*/
3443 createLabel (symbol * label, ast * stmnt)
3446 char name[SDCC_NAME_MAX + 1];
3449 /* must create fresh symbol if the symbol name */
3450 /* exists in the symbol table, since there can */
3451 /* be a variable with the same name as the labl */
3452 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3453 (csym->level == label->level))
3454 label = newSymbol (label->name, label->level);
3456 /* change the name before putting it in add _ */
3457 sprintf (name, "%s", label->name);
3459 /* put the label in the LabelSymbol table */
3460 /* but first check if a label of the same */
3462 if ((csym = findSym (LabelTab, NULL, name)))
3463 werror (E_DUPLICATE_LABEL, label->name);
3465 addSym (LabelTab, label, name, label->level, 0, 0);
3468 label->key = labelKey++;
3469 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3475 /*-----------------------------------------------------------------*/
3476 /* createCase - generates the parsetree for a case statement */
3477 /*-----------------------------------------------------------------*/
3479 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3481 char caseLbl[SDCC_NAME_MAX + 1];
3485 /* if the switch statement does not exist */
3486 /* then case is out of context */
3489 werror (E_CASE_CONTEXT);
3493 caseVal = decorateType (resolveSymbols (caseVal));
3494 /* if not a constant then error */
3495 if (!IS_LITERAL (caseVal->ftype))
3497 werror (E_CASE_CONSTANT);
3501 /* if not a integer than error */
3502 if (!IS_INTEGRAL (caseVal->ftype))
3504 werror (E_CASE_NON_INTEGER);
3508 /* find the end of the switch values chain */
3509 if (!(val = swStat->values.switchVals.swVals))
3510 swStat->values.switchVals.swVals = caseVal->opval.val;
3513 /* also order the cases according to value */
3515 int cVal = (int) floatFromVal (caseVal->opval.val);
3516 while (val && (int) floatFromVal (val) < cVal)
3522 /* if we reached the end then */
3525 pval->next = caseVal->opval.val;
3529 /* we found a value greater than */
3530 /* the current value we must add this */
3531 /* before the value */
3532 caseVal->opval.val->next = val;
3534 /* if this was the first in chain */
3535 if (swStat->values.switchVals.swVals == val)
3536 swStat->values.switchVals.swVals =
3539 pval->next = caseVal->opval.val;
3544 /* create the case label */
3545 sprintf (caseLbl, "_case_%d_%d",
3546 swStat->values.switchVals.swNum,
3547 (int) floatFromVal (caseVal->opval.val));
3549 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3554 /*-----------------------------------------------------------------*/
3555 /* createDefault - creates the parse tree for the default statement */
3556 /*-----------------------------------------------------------------*/
3558 createDefault (ast * swStat, ast * stmnt)
3560 char defLbl[SDCC_NAME_MAX + 1];
3562 /* if the switch statement does not exist */
3563 /* then case is out of context */
3566 werror (E_CASE_CONTEXT);
3570 /* turn on the default flag */
3571 swStat->values.switchVals.swDefault = 1;
3573 /* create the label */
3574 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3575 return createLabel (newSymbol (defLbl, 0), stmnt);
3578 /*-----------------------------------------------------------------*/
3579 /* createIf - creates the parsetree for the if statement */
3580 /*-----------------------------------------------------------------*/
3582 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3584 static int Lblnum = 0;
3586 symbol *ifTrue, *ifFalse, *ifEnd;
3588 /* if neither exists */
3589 if (!elseBody && !ifBody)
3592 /* create the labels */
3593 sprintf (buffer, "_iffalse_%d", Lblnum);
3594 ifFalse = newSymbol (buffer, NestLevel);
3595 /* if no else body then end == false */
3600 sprintf (buffer, "_ifend_%d", Lblnum);
3601 ifEnd = newSymbol (buffer, NestLevel);
3604 sprintf (buffer, "_iftrue_%d", Lblnum);
3605 ifTrue = newSymbol (buffer, NestLevel);
3609 /* attach the ifTrue label to the top of it body */
3610 ifBody = createLabel (ifTrue, ifBody);
3611 /* attach a goto end to the ifBody if else is present */
3614 ifBody = newNode (NULLOP, ifBody,
3616 newAst_VALUE (symbolVal (ifEnd)),
3618 /* put the elseLabel on the else body */
3619 elseBody = createLabel (ifFalse, elseBody);
3620 /* out the end at the end of the body */
3621 elseBody = newNode (NULLOP,
3623 createLabel (ifEnd, NULL));
3627 ifBody = newNode (NULLOP, ifBody,
3628 createLabel (ifFalse, NULL));
3630 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3631 if (IS_IFX (condAst))
3634 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3636 return newNode (NULLOP, ifTree,
3637 newNode (NULLOP, ifBody, elseBody));
3641 /*-----------------------------------------------------------------*/
3642 /* createDo - creates parse tree for do */
3645 /* _docontinue_n: */
3646 /* condition_expression +-> trueLabel -> _dobody_n */
3648 /* +-> falseLabel-> _dobreak_n */
3650 /*-----------------------------------------------------------------*/
3652 createDo (symbol * trueLabel, symbol * continueLabel,
3653 symbol * falseLabel, ast * condAst, ast * doBody)
3658 /* if the body does not exist then it is simple */
3661 condAst = backPatchLabels (condAst, continueLabel, NULL);
3662 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3663 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3664 doTree->trueLabel = continueLabel;
3665 doTree->falseLabel = NULL;
3669 /* otherwise we have a body */
3670 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3672 /* attach the body label to the top */
3673 doBody = createLabel (trueLabel, doBody);
3674 /* attach the continue label to end of body */
3675 doBody = newNode (NULLOP, doBody,
3676 createLabel (continueLabel, NULL));
3678 /* now put the break label at the end */
3679 if (IS_IFX (condAst))
3682 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3684 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3686 /* putting it together */
3687 return newNode (NULLOP, doBody, doTree);
3690 /*-----------------------------------------------------------------*/
3691 /* createFor - creates parse tree for 'for' statement */
3694 /* condExpr +-> trueLabel -> _forbody_n */
3696 /* +-> falseLabel-> _forbreak_n */
3699 /* _forcontinue_n: */
3701 /* goto _forcond_n ; */
3703 /*-----------------------------------------------------------------*/
3705 createFor (symbol * trueLabel, symbol * continueLabel,
3706 symbol * falseLabel, symbol * condLabel,
3707 ast * initExpr, ast * condExpr, ast * loopExpr,
3712 /* if loopexpression not present then we can generate it */
3713 /* the same way as a while */
3715 return newNode (NULLOP, initExpr,
3716 createWhile (trueLabel, continueLabel,
3717 falseLabel, condExpr, forBody));
3718 /* vanilla for statement */
3719 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3721 if (condExpr && !IS_IFX (condExpr))
3722 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3725 /* attach condition label to condition */
3726 condExpr = createLabel (condLabel, condExpr);
3728 /* attach body label to body */
3729 forBody = createLabel (trueLabel, forBody);
3731 /* attach continue to forLoop expression & attach */
3732 /* goto the forcond @ and of loopExpression */
3733 loopExpr = createLabel (continueLabel,
3737 newAst_VALUE (symbolVal (condLabel)),
3739 /* now start putting them together */
3740 forTree = newNode (NULLOP, initExpr, condExpr);
3741 forTree = newNode (NULLOP, forTree, forBody);
3742 forTree = newNode (NULLOP, forTree, loopExpr);
3743 /* finally add the break label */
3744 forTree = newNode (NULLOP, forTree,
3745 createLabel (falseLabel, NULL));
3749 /*-----------------------------------------------------------------*/
3750 /* createWhile - creates parse tree for while statement */
3751 /* the while statement will be created as follows */
3753 /* _while_continue_n: */
3754 /* condition_expression +-> trueLabel -> _while_boby_n */
3756 /* +-> falseLabel -> _while_break_n */
3757 /* _while_body_n: */
3759 /* goto _while_continue_n */
3760 /* _while_break_n: */
3761 /*-----------------------------------------------------------------*/
3763 createWhile (symbol * trueLabel, symbol * continueLabel,
3764 symbol * falseLabel, ast * condExpr, ast * whileBody)
3768 /* put the continue label */
3769 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3770 condExpr = createLabel (continueLabel, condExpr);
3771 condExpr->lineno = 0;
3773 /* put the body label in front of the body */
3774 whileBody = createLabel (trueLabel, whileBody);
3775 whileBody->lineno = 0;
3776 /* put a jump to continue at the end of the body */
3777 /* and put break label at the end of the body */
3778 whileBody = newNode (NULLOP,
3781 newAst_VALUE (symbolVal (continueLabel)),
3782 createLabel (falseLabel, NULL)));
3784 /* put it all together */
3785 if (IS_IFX (condExpr))
3786 whileTree = condExpr;
3789 whileTree = newNode (IFX, condExpr, NULL);
3790 /* put the true & false labels in place */
3791 whileTree->trueLabel = trueLabel;
3792 whileTree->falseLabel = falseLabel;
3795 return newNode (NULLOP, whileTree, whileBody);
3798 /*-----------------------------------------------------------------*/
3799 /* optimizeGetHbit - get highest order bit of the expression */
3800 /*-----------------------------------------------------------------*/
3802 optimizeGetHbit (ast * tree)
3805 /* if this is not a bit and */
3806 if (!IS_BITAND (tree))
3809 /* will look for tree of the form
3810 ( expr >> ((sizeof expr) -1) ) & 1 */
3811 if (!IS_AST_LIT_VALUE (tree->right))
3814 if (AST_LIT_VALUE (tree->right) != 1)
3817 if (!IS_RIGHT_OP (tree->left))
3820 if (!IS_AST_LIT_VALUE (tree->left->right))
3823 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3824 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3827 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3831 /*-----------------------------------------------------------------*/
3832 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3833 /*-----------------------------------------------------------------*/
3835 optimizeRRCRLC (ast * root)
3837 /* will look for trees of the form
3838 (?expr << 1) | (?expr >> 7) or
3839 (?expr >> 7) | (?expr << 1) will make that
3840 into a RLC : operation ..
3842 (?expr >> 1) | (?expr << 7) or
3843 (?expr << 7) | (?expr >> 1) will make that
3844 into a RRC operation
3845 note : by 7 I mean (number of bits required to hold the
3847 /* if the root operations is not a | operation the not */
3848 if (!IS_BITOR (root))
3851 /* I have to think of a better way to match patterns this sucks */
3852 /* that aside let start looking for the first case : I use a the
3853 negative check a lot to improve the efficiency */
3854 /* (?expr << 1) | (?expr >> 7) */
3855 if (IS_LEFT_OP (root->left) &&
3856 IS_RIGHT_OP (root->right))
3859 if (!SPEC_USIGN (TETYPE (root->left->left)))
3862 if (!IS_AST_LIT_VALUE (root->left->right) ||
3863 !IS_AST_LIT_VALUE (root->right->right))
3866 /* make sure it is the same expression */
3867 if (!isAstEqual (root->left->left,
3871 if (AST_LIT_VALUE (root->left->right) != 1)
3874 if (AST_LIT_VALUE (root->right->right) !=
3875 (getSize (TTYPE (root->left->left)) * 8 - 1))
3878 /* whew got the first case : create the AST */
3879 return newNode (RLC, root->left->left, NULL);
3883 /* check for second case */
3884 /* (?expr >> 7) | (?expr << 1) */
3885 if (IS_LEFT_OP (root->right) &&
3886 IS_RIGHT_OP (root->left))
3889 if (!SPEC_USIGN (TETYPE (root->left->left)))
3892 if (!IS_AST_LIT_VALUE (root->left->right) ||
3893 !IS_AST_LIT_VALUE (root->right->right))
3896 /* make sure it is the same symbol */
3897 if (!isAstEqual (root->left->left,
3901 if (AST_LIT_VALUE (root->right->right) != 1)
3904 if (AST_LIT_VALUE (root->left->right) !=
3905 (getSize (TTYPE (root->left->left)) * 8 - 1))
3908 /* whew got the first case : create the AST */
3909 return newNode (RLC, root->left->left, NULL);
3914 /* third case for RRC */
3915 /* (?symbol >> 1) | (?symbol << 7) */
3916 if (IS_LEFT_OP (root->right) &&
3917 IS_RIGHT_OP (root->left))
3920 if (!SPEC_USIGN (TETYPE (root->left->left)))
3923 if (!IS_AST_LIT_VALUE (root->left->right) ||
3924 !IS_AST_LIT_VALUE (root->right->right))
3927 /* make sure it is the same symbol */
3928 if (!isAstEqual (root->left->left,
3932 if (AST_LIT_VALUE (root->left->right) != 1)
3935 if (AST_LIT_VALUE (root->right->right) !=
3936 (getSize (TTYPE (root->left->left)) * 8 - 1))
3939 /* whew got the first case : create the AST */
3940 return newNode (RRC, root->left->left, NULL);
3944 /* fourth and last case for now */
3945 /* (?symbol << 7) | (?symbol >> 1) */
3946 if (IS_RIGHT_OP (root->right) &&
3947 IS_LEFT_OP (root->left))
3950 if (!SPEC_USIGN (TETYPE (root->left->left)))
3953 if (!IS_AST_LIT_VALUE (root->left->right) ||
3954 !IS_AST_LIT_VALUE (root->right->right))
3957 /* make sure it is the same symbol */
3958 if (!isAstEqual (root->left->left,
3962 if (AST_LIT_VALUE (root->right->right) != 1)
3965 if (AST_LIT_VALUE (root->left->right) !=
3966 (getSize (TTYPE (root->left->left)) * 8 - 1))
3969 /* whew got the first case : create the AST */
3970 return newNode (RRC, root->left->left, NULL);
3974 /* not found return root */
3978 /*-----------------------------------------------------------------*/
3979 /* optimizeCompare - otimizes compares for bit variables */
3980 /*-----------------------------------------------------------------*/
3982 optimizeCompare (ast * root)
3984 ast *optExpr = NULL;
3987 unsigned int litValue;
3989 /* if nothing then return nothing */
3993 /* if not a compare op then do leaves */
3994 if (!IS_COMPARE_OP (root))
3996 root->left = optimizeCompare (root->left);
3997 root->right = optimizeCompare (root->right);
4001 /* if left & right are the same then depending
4002 of the operation do */
4003 if (isAstEqual (root->left, root->right))
4005 switch (root->opval.op)
4010 optExpr = newAst_VALUE (constVal ("0"));
4015 optExpr = newAst_VALUE (constVal ("1"));
4019 return decorateType (optExpr);
4022 vleft = (root->left->type == EX_VALUE ?
4023 root->left->opval.val : NULL);
4025 vright = (root->right->type == EX_VALUE ?
4026 root->right->opval.val : NULL);
4028 /* if left is a BITVAR in BITSPACE */
4029 /* and right is a LITERAL then opt- */
4030 /* imize else do nothing */
4031 if (vleft && vright &&
4032 IS_BITVAR (vleft->etype) &&
4033 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4034 IS_LITERAL (vright->etype))
4037 /* if right side > 1 then comparison may never succeed */
4038 if ((litValue = (int) floatFromVal (vright)) > 1)
4040 werror (W_BAD_COMPARE);
4046 switch (root->opval.op)
4048 case '>': /* bit value greater than 1 cannot be */
4049 werror (W_BAD_COMPARE);
4053 case '<': /* bit value < 1 means 0 */
4055 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4058 case LE_OP: /* bit value <= 1 means no check */
4059 optExpr = newAst_VALUE (vright);
4062 case GE_OP: /* bit value >= 1 means only check for = */
4064 optExpr = newAst_VALUE (vleft);
4069 { /* literal is zero */
4070 switch (root->opval.op)
4072 case '<': /* bit value < 0 cannot be */
4073 werror (W_BAD_COMPARE);
4077 case '>': /* bit value > 0 means 1 */
4079 optExpr = newAst_VALUE (vleft);
4082 case LE_OP: /* bit value <= 0 means no check */
4083 case GE_OP: /* bit value >= 0 means no check */
4084 werror (W_BAD_COMPARE);
4088 case EQ_OP: /* bit == 0 means ! of bit */
4089 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4093 return decorateType (resolveSymbols (optExpr));
4094 } /* end-of-if of BITVAR */
4099 /*-----------------------------------------------------------------*/
4100 /* addSymToBlock : adds the symbol to the first block we find */
4101 /*-----------------------------------------------------------------*/
4103 addSymToBlock (symbol * sym, ast * tree)
4105 /* reached end of tree or a leaf */
4106 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4110 if (IS_AST_OP (tree) &&
4111 tree->opval.op == BLOCK)
4114 symbol *lsym = copySymbol (sym);
4116 lsym->next = AST_VALUES (tree, sym);
4117 AST_VALUES (tree, sym) = lsym;
4121 addSymToBlock (sym, tree->left);
4122 addSymToBlock (sym, tree->right);
4125 /*-----------------------------------------------------------------*/
4126 /* processRegParms - do processing for register parameters */
4127 /*-----------------------------------------------------------------*/
4129 processRegParms (value * args, ast * body)
4133 if (IS_REGPARM (args->etype))
4134 addSymToBlock (args->sym, body);
4139 /*-----------------------------------------------------------------*/
4140 /* resetParmKey - resets the operandkeys for the symbols */
4141 /*-----------------------------------------------------------------*/
4142 DEFSETFUNC (resetParmKey)
4153 /*-----------------------------------------------------------------*/
4154 /* createFunction - This is the key node that calls the iCode for */
4155 /* generating the code for a function. Note code */
4156 /* is generated function by function, later when */
4157 /* add inter-procedural analysis this will change */
4158 /*-----------------------------------------------------------------*/
4160 createFunction (symbol * name, ast * body)
4166 iCode *piCode = NULL;
4168 /* if check function return 0 then some problem */
4169 if (checkFunction (name) == 0)
4172 /* create a dummy block if none exists */
4174 body = newNode (BLOCK, NULL, NULL);
4178 /* check if the function name already in the symbol table */
4179 if ((csym = findSym (SymbolTab, NULL, name->name)))
4182 /* special case for compiler defined functions
4183 we need to add the name to the publics list : this
4184 actually means we are now compiling the compiler
4188 addSet (&publics, name);
4194 allocVariables (name);
4196 name->lastLine = yylineno;
4198 processFuncArgs (currFunc, 0);
4200 /* set the stack pointer */
4201 /* PENDING: check this for the mcs51 */
4202 stackPtr = -port->stack.direction * port->stack.call_overhead;
4203 if (IS_ISR (name->etype))
4204 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4205 if (IS_RENT (name->etype) || options.stackAuto)
4206 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4208 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4210 fetype = getSpec (name->type); /* get the specifier for the function */
4211 /* if this is a reentrant function then */
4212 if (IS_RENT (fetype))
4215 allocParms (name->args); /* allocate the parameters */
4217 /* do processing for parameters that are passed in registers */
4218 processRegParms (name->args, body);
4220 /* set the stack pointer */
4224 /* allocate & autoinit the block variables */
4225 processBlockVars (body, &stack, ALLOCATE);
4227 /* save the stack information */
4228 if (options.useXstack)
4229 name->xstack = SPEC_STAK (fetype) = stack;
4231 name->stack = SPEC_STAK (fetype) = stack;
4233 /* name needs to be mangled */
4234 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4236 body = resolveSymbols (body); /* resolve the symbols */
4237 body = decorateType (body); /* propagateType & do semantic checks */
4239 ex = newAst_VALUE (symbolVal (name)); /* create name */
4240 ex = newNode (FUNCTION, ex, body);
4241 ex->values.args = name->args;
4245 werror (E_FUNC_NO_CODE, name->name);
4249 /* create the node & generate intermediate code */
4251 codeOutFile = code->oFile;
4252 piCode = iCodeFromAst (ex);
4256 werror (E_FUNC_NO_CODE, name->name);
4260 eBBlockFromiCode (piCode);
4262 /* if there are any statics then do them */
4265 GcurMemmap = statsg;
4266 codeOutFile = statsg->oFile;
4267 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4273 /* dealloc the block variables */
4274 processBlockVars (body, &stack, DEALLOCATE);
4275 /* deallocate paramaters */
4276 deallocParms (name->args);
4278 if (IS_RENT (fetype))
4281 /* we are done freeup memory & cleanup */
4286 addSet (&operKeyReset, name);
4287 applyToSet (operKeyReset, resetParmKey);
4290 cdbStructBlock (1, cdbFile);
4292 cleanUpLevel (LabelTab, 0);
4293 cleanUpBlock (StructTab, 1);
4294 cleanUpBlock (TypedefTab, 1);
4296 xstack->syms = NULL;
4297 istack->syms = NULL;
4302 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4303 /*-----------------------------------------------------------------*/
4304 /* ast_print : prints the ast (for debugging purposes) */
4305 /*-----------------------------------------------------------------*/
4307 void ast_print (ast * tree, FILE *outfile, int indent)
4312 /* can print only decorated trees */
4313 if (!tree->decorated) return;
4315 /* if any child is an error | this one is an error do nothing */
4316 if (tree->isError ||
4317 (tree->left && tree->left->isError) ||
4318 (tree->right && tree->right->isError)) {
4319 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4323 /* print the line */
4324 /* if not block & function */
4325 if (tree->type == EX_OP &&
4326 (tree->opval.op != FUNCTION &&
4327 tree->opval.op != BLOCK &&
4328 tree->opval.op != NULLOP)) {
4331 if (tree->opval.op == FUNCTION) {
4332 fprintf(outfile,"FUNCTION (%p) type (",tree);
4333 printTypeChain (tree->ftype,outfile);
4334 fprintf(outfile,")\n");
4335 ast_print(tree->left,outfile,indent+4);
4336 ast_print(tree->right,outfile,indent+4);
4339 if (tree->opval.op == BLOCK) {
4340 symbol *decls = tree->values.sym;
4341 fprintf(outfile,"{\n");
4343 INDENT(indent+4,outfile);
4344 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4345 printTypeChain(decls->type,outfile);
4346 fprintf(outfile,")\n");
4348 decls = decls->next;
4350 ast_print(tree->right,outfile,indent+4);
4351 fprintf(outfile,"}\n");
4354 if (tree->opval.op == NULLOP) {
4355 fprintf(outfile,"\n");
4356 ast_print(tree->left,outfile,indent);
4357 fprintf(outfile,"\n");
4358 ast_print(tree->right,outfile,indent);
4361 INDENT(indent,outfile);
4363 /*------------------------------------------------------------------*/
4364 /*----------------------------*/
4365 /* leaf has been reached */
4366 /*----------------------------*/
4367 /* if this is of type value */
4368 /* just get the type */
4369 if (tree->type == EX_VALUE) {
4371 if (IS_LITERAL (tree->opval.val->etype)) {
4372 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4373 (int) floatFromVal(tree->opval.val),
4374 (int) floatFromVal(tree->opval.val),
4375 floatFromVal(tree->opval.val));
4376 } else if (tree->opval.val->sym) {
4377 /* if the undefined flag is set then give error message */
4378 if (tree->opval.val->sym->undefined) {
4379 fprintf(outfile,"UNDEFINED SYMBOL ");
4381 fprintf(outfile,"SYMBOL ");
4383 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4386 fprintf(outfile," type (");
4387 printTypeChain(tree->ftype,outfile);
4388 fprintf(outfile,")\n");
4390 fprintf(outfile,"\n");
4395 /* if type link for the case of cast */
4396 if (tree->type == EX_LINK) {
4397 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4398 printTypeChain(tree->opval.lnk,outfile);
4399 fprintf(outfile,")\n");
4404 /* depending on type of operator do */
4406 switch (tree->opval.op) {
4407 /*------------------------------------------------------------------*/
4408 /*----------------------------*/
4410 /*----------------------------*/
4412 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4413 printTypeChain(tree->ftype,outfile);
4414 fprintf(outfile,")\n");
4415 ast_print(tree->left,outfile,indent+4);
4416 ast_print(tree->right,outfile,indent+4);
4419 /*------------------------------------------------------------------*/
4420 /*----------------------------*/
4422 /*----------------------------*/
4424 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4425 printTypeChain(tree->ftype,outfile);
4426 fprintf(outfile,")\n");
4427 ast_print(tree->left,outfile,indent+4);
4428 ast_print(tree->right,outfile,indent+4);
4431 /*------------------------------------------------------------------*/
4432 /*----------------------------*/
4433 /* struct/union pointer */
4434 /*----------------------------*/
4436 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4437 printTypeChain(tree->ftype,outfile);
4438 fprintf(outfile,")\n");
4439 ast_print(tree->left,outfile,indent+4);
4440 ast_print(tree->right,outfile,indent+4);
4443 /*------------------------------------------------------------------*/
4444 /*----------------------------*/
4445 /* ++/-- operation */
4446 /*----------------------------*/
4447 case INC_OP: /* incerement operator unary so left only */
4448 fprintf(outfile,"INC_OP (%p) type (",tree);
4449 printTypeChain(tree->ftype,outfile);
4450 fprintf(outfile,")\n");
4451 ast_print(tree->left,outfile,indent+4);
4455 fprintf(outfile,"DEC_OP (%p) type (",tree);
4456 printTypeChain(tree->ftype,outfile);
4457 fprintf(outfile,")\n");
4458 ast_print(tree->left,outfile,indent+4);
4461 /*------------------------------------------------------------------*/
4462 /*----------------------------*/
4464 /*----------------------------*/
4467 fprintf(outfile,"& (%p) type (",tree);
4468 printTypeChain(tree->ftype,outfile);
4469 fprintf(outfile,")\n");
4470 ast_print(tree->left,outfile,indent+4);
4471 ast_print(tree->right,outfile,indent+4);
4473 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4474 printTypeChain(tree->ftype,outfile);
4475 fprintf(outfile,")\n");
4476 ast_print(tree->left,outfile,indent+4);
4477 ast_print(tree->right,outfile,indent+4);
4480 /*----------------------------*/
4482 /*----------------------------*/
4484 fprintf(outfile,"OR (%p) type (",tree);
4485 printTypeChain(tree->ftype,outfile);
4486 fprintf(outfile,")\n");
4487 ast_print(tree->left,outfile,indent+4);
4488 ast_print(tree->right,outfile,indent+4);
4490 /*------------------------------------------------------------------*/
4491 /*----------------------------*/
4493 /*----------------------------*/
4495 fprintf(outfile,"XOR (%p) type (",tree);
4496 printTypeChain(tree->ftype,outfile);
4497 fprintf(outfile,")\n");
4498 ast_print(tree->left,outfile,indent+4);
4499 ast_print(tree->right,outfile,indent+4);
4502 /*------------------------------------------------------------------*/
4503 /*----------------------------*/
4505 /*----------------------------*/
4507 fprintf(outfile,"DIV (%p) type (",tree);
4508 printTypeChain(tree->ftype,outfile);
4509 fprintf(outfile,")\n");
4510 ast_print(tree->left,outfile,indent+4);
4511 ast_print(tree->right,outfile,indent+4);
4513 /*------------------------------------------------------------------*/
4514 /*----------------------------*/
4516 /*----------------------------*/
4518 fprintf(outfile,"MOD (%p) type (",tree);
4519 printTypeChain(tree->ftype,outfile);
4520 fprintf(outfile,")\n");
4521 ast_print(tree->left,outfile,indent+4);
4522 ast_print(tree->right,outfile,indent+4);
4525 /*------------------------------------------------------------------*/
4526 /*----------------------------*/
4527 /* address dereference */
4528 /*----------------------------*/
4529 case '*': /* can be unary : if right is null then unary operation */
4531 fprintf(outfile,"DEREF (%p) type (",tree);
4532 printTypeChain(tree->ftype,outfile);
4533 fprintf(outfile,")\n");
4534 ast_print(tree->left,outfile,indent+4);
4537 /*------------------------------------------------------------------*/
4538 /*----------------------------*/
4539 /* multiplication */
4540 /*----------------------------*/
4541 fprintf(outfile,"MULT (%p) type (",tree);
4542 printTypeChain(tree->ftype,outfile);
4543 fprintf(outfile,")\n");
4544 ast_print(tree->left,outfile,indent+4);
4545 ast_print(tree->right,outfile,indent+4);
4549 /*------------------------------------------------------------------*/
4550 /*----------------------------*/
4551 /* unary '+' operator */
4552 /*----------------------------*/
4556 fprintf(outfile,"UPLUS (%p) type (",tree);
4557 printTypeChain(tree->ftype,outfile);
4558 fprintf(outfile,")\n");
4559 ast_print(tree->left,outfile,indent+4);
4561 /*------------------------------------------------------------------*/
4562 /*----------------------------*/
4564 /*----------------------------*/
4565 fprintf(outfile,"ADD (%p) type (",tree);
4566 printTypeChain(tree->ftype,outfile);
4567 fprintf(outfile,")\n");
4568 ast_print(tree->left,outfile,indent+4);
4569 ast_print(tree->right,outfile,indent+4);
4572 /*------------------------------------------------------------------*/
4573 /*----------------------------*/
4575 /*----------------------------*/
4576 case '-': /* can be unary */
4578 fprintf(outfile,"UMINUS (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+4);
4583 /*------------------------------------------------------------------*/
4584 /*----------------------------*/
4586 /*----------------------------*/
4587 fprintf(outfile,"SUB (%p) type (",tree);
4588 printTypeChain(tree->ftype,outfile);
4589 fprintf(outfile,")\n");
4590 ast_print(tree->left,outfile,indent+4);
4591 ast_print(tree->right,outfile,indent+4);
4594 /*------------------------------------------------------------------*/
4595 /*----------------------------*/
4597 /*----------------------------*/
4599 fprintf(outfile,"COMPL (%p) type (",tree);
4600 printTypeChain(tree->ftype,outfile);
4601 fprintf(outfile,")\n");
4602 ast_print(tree->left,outfile,indent+4);
4604 /*------------------------------------------------------------------*/
4605 /*----------------------------*/
4607 /*----------------------------*/
4609 fprintf(outfile,"NOT (%p) type (",tree);
4610 printTypeChain(tree->ftype,outfile);
4611 fprintf(outfile,")\n");
4612 ast_print(tree->left,outfile,indent+4);
4614 /*------------------------------------------------------------------*/
4615 /*----------------------------*/
4617 /*----------------------------*/
4619 fprintf(outfile,"RRC (%p) type (",tree);
4620 printTypeChain(tree->ftype,outfile);
4621 fprintf(outfile,")\n");
4622 ast_print(tree->left,outfile,indent+4);
4626 fprintf(outfile,"RLC (%p) type (",tree);
4627 printTypeChain(tree->ftype,outfile);
4628 fprintf(outfile,")\n");
4629 ast_print(tree->left,outfile,indent+4);
4632 fprintf(outfile,"GETHBIT (%p) type (",tree);
4633 printTypeChain(tree->ftype,outfile);
4634 fprintf(outfile,")\n");
4635 ast_print(tree->left,outfile,indent+4);
4638 fprintf(outfile,"LEFT_SHIFT (%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 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4646 printTypeChain(tree->ftype,outfile);
4647 fprintf(outfile,")\n");
4648 ast_print(tree->left,outfile,indent+4);
4649 ast_print(tree->right,outfile,indent+4);
4651 /*------------------------------------------------------------------*/
4652 /*----------------------------*/
4654 /*----------------------------*/
4655 case CAST: /* change the type */
4656 fprintf(outfile,"CAST (%p) type (",tree);
4657 printTypeChain(tree->ftype,outfile);
4658 fprintf(outfile,")\n");
4659 ast_print(tree->right,outfile,indent+4);
4663 fprintf(outfile,"ANDAND (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+4);
4667 ast_print(tree->right,outfile,indent+4);
4670 fprintf(outfile,"OROR (%p) type (",tree);
4671 printTypeChain(tree->ftype,outfile);
4672 fprintf(outfile,")\n");
4673 ast_print(tree->left,outfile,indent+4);
4674 ast_print(tree->right,outfile,indent+4);
4677 /*------------------------------------------------------------------*/
4678 /*----------------------------*/
4679 /* comparison operators */
4680 /*----------------------------*/
4682 fprintf(outfile,"GT(>) (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+4);
4686 ast_print(tree->right,outfile,indent+4);
4689 fprintf(outfile,"LT(<) (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+4);
4693 ast_print(tree->right,outfile,indent+4);
4696 fprintf(outfile,"LE(<=) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+4);
4700 ast_print(tree->right,outfile,indent+4);
4703 fprintf(outfile,"GE(>=) (%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,"EQ(==) (%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 fprintf(outfile,"NE(!=) (%p) type (",tree);
4718 printTypeChain(tree->ftype,outfile);
4719 fprintf(outfile,")\n");
4720 ast_print(tree->left,outfile,indent+4);
4721 ast_print(tree->right,outfile,indent+4);
4722 /*------------------------------------------------------------------*/
4723 /*----------------------------*/
4725 /*----------------------------*/
4726 case SIZEOF: /* evaluate wihout code generation */
4727 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4730 /*------------------------------------------------------------------*/
4731 /*----------------------------*/
4732 /* conditional operator '?' */
4733 /*----------------------------*/
4735 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+4);
4739 ast_print(tree->right,outfile,indent+4);
4742 fprintf(outfile,"COLON(:) (%p) type (",tree);
4743 printTypeChain(tree->ftype,outfile);
4744 fprintf(outfile,")\n");
4745 ast_print(tree->left,outfile,indent+4);
4746 ast_print(tree->right,outfile,indent+4);
4749 /*------------------------------------------------------------------*/
4750 /*----------------------------*/
4751 /* assignment operators */
4752 /*----------------------------*/
4754 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4755 printTypeChain(tree->ftype,outfile);
4756 fprintf(outfile,")\n");
4757 ast_print(tree->left,outfile,indent+4);
4758 ast_print(tree->right,outfile,indent+4);
4761 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4762 printTypeChain(tree->ftype,outfile);
4763 fprintf(outfile,")\n");
4764 ast_print(tree->left,outfile,indent+4);
4765 ast_print(tree->right,outfile,indent+4);
4768 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4769 printTypeChain(tree->ftype,outfile);
4770 fprintf(outfile,")\n");
4771 ast_print(tree->left,outfile,indent+4);
4772 ast_print(tree->right,outfile,indent+4);
4775 fprintf(outfile,"ORASS(*=) (%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);
4782 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4783 printTypeChain(tree->ftype,outfile);
4784 fprintf(outfile,")\n");
4785 ast_print(tree->left,outfile,indent+4);
4786 ast_print(tree->right,outfile,indent+4);
4789 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4790 printTypeChain(tree->ftype,outfile);
4791 fprintf(outfile,")\n");
4792 ast_print(tree->left,outfile,indent+4);
4793 ast_print(tree->right,outfile,indent+4);
4796 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4797 printTypeChain(tree->ftype,outfile);
4798 fprintf(outfile,")\n");
4799 ast_print(tree->left,outfile,indent+4);
4800 ast_print(tree->right,outfile,indent+4);
4802 /*------------------------------------------------------------------*/
4803 /*----------------------------*/
4805 /*----------------------------*/
4807 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4808 printTypeChain(tree->ftype,outfile);
4809 fprintf(outfile,")\n");
4810 ast_print(tree->left,outfile,indent+4);
4811 ast_print(tree->right,outfile,indent+4);
4813 /*------------------------------------------------------------------*/
4814 /*----------------------------*/
4816 /*----------------------------*/
4818 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4819 printTypeChain(tree->ftype,outfile);
4820 fprintf(outfile,")\n");
4821 ast_print(tree->left,outfile,indent+4);
4822 ast_print(tree->right,outfile,indent+4);
4824 /*------------------------------------------------------------------*/
4825 /*----------------------------*/
4826 /* straight assignemnt */
4827 /*----------------------------*/
4829 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4830 printTypeChain(tree->ftype,outfile);
4831 fprintf(outfile,")\n");
4832 ast_print(tree->left,outfile,indent+4);
4833 ast_print(tree->right,outfile,indent+4);
4835 /*------------------------------------------------------------------*/
4836 /*----------------------------*/
4837 /* comma operator */
4838 /*----------------------------*/
4840 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4841 printTypeChain(tree->ftype,outfile);
4842 fprintf(outfile,")\n");
4843 ast_print(tree->left,outfile,indent+4);
4844 ast_print(tree->right,outfile,indent+4);
4846 /*------------------------------------------------------------------*/
4847 /*----------------------------*/
4849 /*----------------------------*/
4852 fprintf(outfile,"CALL (%p) type (",tree);
4853 printTypeChain(tree->ftype,outfile);
4854 fprintf(outfile,")\n");
4855 ast_print(tree->left,outfile,indent+4);
4856 ast_print(tree->right,outfile,indent+4);
4859 fprintf(outfile,"PARM ");
4860 ast_print(tree->left,outfile,indent+4);
4861 if (tree->right && !IS_AST_PARAM(tree->right)) {
4862 fprintf(outfile,"PARM ");
4863 ast_print(tree->right,outfile,indent+4);
4866 /*------------------------------------------------------------------*/
4867 /*----------------------------*/
4868 /* return statement */
4869 /*----------------------------*/
4871 fprintf(outfile,"RETURN (%p) type (",tree);
4872 printTypeChain(tree->right->ftype,outfile);
4873 fprintf(outfile,")\n");
4874 ast_print(tree->right,outfile,indent+4);
4876 /*------------------------------------------------------------------*/
4877 /*----------------------------*/
4878 /* label statement */
4879 /*----------------------------*/
4881 fprintf(outfile,"LABEL (%p)",tree);
4882 ast_print(tree->left,outfile,indent+4);
4883 ast_print(tree->right,outfile,indent);
4885 /*------------------------------------------------------------------*/
4886 /*----------------------------*/
4887 /* switch statement */
4888 /*----------------------------*/
4892 fprintf(outfile,"SWITCH (%p) ",tree);
4893 ast_print(tree->left,outfile,0);
4894 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4895 INDENT(indent+4,outfile);
4896 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4897 (int) floatFromVal(val),
4898 tree->values.switchVals.swNum,
4899 (int) floatFromVal(val));
4901 ast_print(tree->right,outfile,indent);
4904 /*------------------------------------------------------------------*/
4905 /*----------------------------*/
4907 /*----------------------------*/
4909 ast_print(tree->left,outfile,indent);
4910 INDENT(indent,outfile);
4911 fprintf(outfile,"IF (%p) \n",tree);
4912 if (tree->trueLabel) {
4913 INDENT(indent,outfile);
4914 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4916 if (tree->falseLabel) {
4917 INDENT(indent,outfile);
4918 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4920 ast_print(tree->right,outfile,indent);
4922 /*------------------------------------------------------------------*/
4923 /*----------------------------*/
4925 /*----------------------------*/
4927 fprintf(outfile,"FOR (%p) \n",tree);
4928 if (AST_FOR( tree, initExpr)) {
4929 INDENT(indent+4,outfile);
4930 fprintf(outfile,"INIT EXPR ");
4931 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4933 if (AST_FOR( tree, condExpr)) {
4934 INDENT(indent+4,outfile);
4935 fprintf(outfile,"COND EXPR ");
4936 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4938 if (AST_FOR( tree, loopExpr)) {
4939 INDENT(indent+4,outfile);
4940 fprintf(outfile,"LOOP EXPR ");
4941 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4943 fprintf(outfile,"FOR LOOP BODY \n");
4944 ast_print(tree->left,outfile,indent+4);
4953 ast_print(t,stdout,1);