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
52 ast *createIval (ast *, sym_link *, initList *, ast *);
53 ast *createIvalCharPtr (ast *, sym_link *, ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
58 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
63 printTypeChain (tree->ftype, stdout);
68 /*-----------------------------------------------------------------*/
69 /* newAst - creates a fresh node for an expression tree */
70 /*-----------------------------------------------------------------*/
73 newAst (int type, void *op)
76 static int oldLineno = 0;
78 Safe_calloc (1, ex, sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
87 /* depending on the type */
91 ex->opval.val = (value *) op;
94 ex->opval.op = (long) op;
97 ex->opval.lnk = (sym_link *) op;
100 ex->opval.stmnt = (unsigned) op;
108 newAst_ (unsigned type)
111 static int oldLineno = 0;
113 ex = Safe_calloc (1, sizeof (ast));
116 ex->lineno = (noLineno ? oldLineno : yylineno);
117 ex->filename = currFname;
118 ex->level = NestLevel;
119 ex->block = currBlockno;
120 ex->initMode = inInitMode;
125 newAst_VALUE (value * val)
127 ast *ex = newAst_ (EX_VALUE);
133 newAst_OP (unsigned op)
135 ast *ex = newAst_ (EX_OP);
141 newAst_LINK (sym_link * val)
143 ast *ex = newAst_ (EX_LINK);
149 newAst_STMNT (unsigned val)
151 ast *ex = newAst_ (EX_STMNT);
152 ex->opval.stmnt = val;
156 /*-----------------------------------------------------------------*/
157 /* newNode - creates a new node */
158 /*-----------------------------------------------------------------*/
160 newNode (long op, ast * left, ast * right)
171 /*-----------------------------------------------------------------*/
172 /* newIfxNode - creates a new Ifx Node */
173 /*-----------------------------------------------------------------*/
175 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
179 /* if this is a literal then we already know the result */
180 if (condAst->etype && IS_LITERAL (condAst->etype))
182 /* then depending on the expression value */
183 if (floatFromVal (condAst->opval.val))
184 ifxNode = newNode (GOTO,
185 newAst_VALUE (symbolVal (trueLabel)),
188 ifxNode = newNode (GOTO,
189 newAst_VALUE (symbolVal (falseLabel)),
194 ifxNode = newNode (IFX, condAst, NULL);
195 ifxNode->trueLabel = trueLabel;
196 ifxNode->falseLabel = falseLabel;
202 /*-----------------------------------------------------------------*/
203 /* copyAstValues - copies value portion of ast if needed */
204 /*-----------------------------------------------------------------*/
206 copyAstValues (ast * dest, ast * src)
208 switch (src->opval.op)
211 dest->values.sym = copySymbolChain (src->values.sym);
215 dest->values.switchVals.swVals =
216 copyValue (src->values.switchVals.swVals);
217 dest->values.switchVals.swDefault =
218 src->values.switchVals.swDefault;
219 dest->values.switchVals.swNum =
220 src->values.switchVals.swNum;
224 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
225 strcpy (dest->values.inlineasm, src->values.inlineasm);
229 dest->values.constlist = copyLiteralList(src->values.constlist);
233 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
234 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
235 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
236 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
237 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
238 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
239 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
244 /*-----------------------------------------------------------------*/
245 /* copyAst - makes a copy of a given astession */
246 /*-----------------------------------------------------------------*/
255 dest = Safe_calloc (1, sizeof (ast));
257 dest->type = src->type;
258 dest->lineno = src->lineno;
259 dest->level = src->level;
260 dest->funcName = src->funcName;
261 dest->argSym = src->argSym;
263 /* if this is a leaf */
265 if (src->type == EX_VALUE)
267 dest->opval.val = copyValue (src->opval.val);
272 if (src->type == EX_LINK)
274 dest->opval.lnk = copyLinkChain (src->opval.lnk);
278 dest->opval.op = src->opval.op;
280 /* if this is a node that has special values */
281 copyAstValues (dest, src);
284 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
286 dest->trueLabel = copySymbol (src->trueLabel);
287 dest->falseLabel = copySymbol (src->falseLabel);
288 dest->left = copyAst (src->left);
289 dest->right = copyAst (src->right);
295 /*-----------------------------------------------------------------*/
296 /* hasSEFcalls - returns TRUE if tree has a function call */
297 /*-----------------------------------------------------------------*/
299 hasSEFcalls (ast * tree)
304 if (tree->type == EX_OP &&
305 (tree->opval.op == CALL ||
306 tree->opval.op == PCALL ||
307 tree->opval.op == '=' ||
308 tree->opval.op == INC_OP ||
309 tree->opval.op == DEC_OP))
312 return (hasSEFcalls (tree->left) |
313 hasSEFcalls (tree->right));
316 /*-----------------------------------------------------------------*/
317 /* isAstEqual - compares two asts & returns 1 if they are equal */
318 /*-----------------------------------------------------------------*/
320 isAstEqual (ast * t1, ast * t2)
329 if (t1->type != t2->type)
335 if (t1->opval.op != t2->opval.op)
337 return (isAstEqual (t1->left, t2->left) &&
338 isAstEqual (t1->right, t2->right));
342 if (t1->opval.val->sym)
344 if (!t2->opval.val->sym)
347 return isSymbolEqual (t1->opval.val->sym,
352 if (t2->opval.val->sym)
355 return (floatFromVal (t1->opval.val) ==
356 floatFromVal (t2->opval.val));
360 /* only compare these two types */
368 /*-----------------------------------------------------------------*/
369 /* resolveSymbols - resolve symbols from the symbol table */
370 /*-----------------------------------------------------------------*/
372 resolveSymbols (ast * tree)
374 /* walk the entire tree and check for values */
375 /* with symbols if we find one then replace */
376 /* symbol with that from the symbol table */
382 /* if not block & function */
383 if (tree->type == EX_OP &&
384 (tree->opval.op != FUNCTION &&
385 tree->opval.op != BLOCK &&
386 tree->opval.op != NULLOP))
388 filename = tree->filename;
389 lineno = tree->lineno;
392 /* make sure we resolve the true & false labels for ifx */
393 if (tree->type == EX_OP && tree->opval.op == IFX)
399 if ((csym = findSym (LabelTab, tree->trueLabel,
400 tree->trueLabel->name)))
401 tree->trueLabel = csym;
403 werror (E_LABEL_UNDEF, tree->trueLabel->name);
406 if (tree->falseLabel)
408 if ((csym = findSym (LabelTab,
410 tree->falseLabel->name)))
411 tree->falseLabel = csym;
413 werror (E_LABEL_UNDEF, tree->falseLabel->name);
418 /* if this is a label resolve it from the labelTab */
419 if (IS_AST_VALUE (tree) &&
420 tree->opval.val->sym &&
421 tree->opval.val->sym->islbl)
424 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
425 tree->opval.val->sym->name);
428 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
430 tree->opval.val->sym = csym;
432 goto resolveChildren;
435 /* do only for leafs */
436 if (IS_AST_VALUE (tree) &&
437 tree->opval.val->sym &&
438 !tree->opval.val->sym->implicit)
441 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
443 /* if found in the symbol table & they r not the same */
444 if (csym && tree->opval.val->sym != csym)
446 tree->opval.val->sym = csym;
447 tree->opval.val->type = csym->type;
448 tree->opval.val->etype = csym->etype;
451 /* if not found in the symbol table */
452 /* mark it as undefined assume it is */
453 /* an integer in data space */
454 if (!csym && !tree->opval.val->sym->implicit)
457 /* if this is a function name then */
458 /* mark it as returning an int */
461 tree->opval.val->sym->type = newLink ();
462 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
463 tree->opval.val->sym->type->next =
464 tree->opval.val->sym->etype = newIntLink ();
465 tree->opval.val->etype = tree->opval.val->etype;
466 tree->opval.val->type = tree->opval.val->sym->type;
467 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
468 allocVariables (tree->opval.val->sym);
472 tree->opval.val->sym->undefined = 1;
473 tree->opval.val->type =
474 tree->opval.val->etype = newIntLink ();
475 tree->opval.val->sym->type =
476 tree->opval.val->sym->etype = newIntLink ();
482 resolveSymbols (tree->left);
483 resolveSymbols (tree->right);
488 /*-----------------------------------------------------------------*/
489 /* setAstLineno - walks a ast tree & sets the line number */
490 /*-----------------------------------------------------------------*/
492 setAstLineno (ast * tree, int lineno)
497 tree->lineno = lineno;
498 setAstLineno (tree->left, lineno);
499 setAstLineno (tree->right, lineno);
504 /* this functions seems to be superfluous?! kmh */
506 /*-----------------------------------------------------------------*/
507 /* resolveFromTable - will return the symbal table value */
508 /*-----------------------------------------------------------------*/
510 resolveFromTable (value * val)
517 csym = findSymWithLevel (SymbolTab, val->sym);
519 /* if found in the symbol table & they r not the same */
520 if (csym && val->sym != csym &&
521 csym->level == val->sym->level &&
527 val->type = csym->type;
528 val->etype = csym->etype;
535 /*-----------------------------------------------------------------*/
536 /* funcOfType :- function of type with name */
537 /*-----------------------------------------------------------------*/
539 funcOfType (char *name, sym_link * type, sym_link * argType,
543 /* create the symbol */
544 sym = newSymbol (name, 0);
546 /* if arguments required */
551 args = sym->args = newValue ();
555 args->type = copyLinkChain (argType);
556 args->etype = getSpec (args->type);
559 args = args->next = newValue ();
563 /* setup return value */
564 sym->type = newLink ();
565 DCL_TYPE (sym->type) = FUNCTION;
566 sym->type->next = copyLinkChain (type);
567 sym->etype = getSpec (sym->type);
568 SPEC_RENT (sym->etype) = rent;
573 allocVariables (sym);
578 /*-----------------------------------------------------------------*/
579 /* reverseParms - will reverse a parameter tree */
580 /*-----------------------------------------------------------------*/
582 reverseParms (ast * ptree)
588 /* top down if we find a nonParm tree then quit */
589 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
592 ptree->left = ptree->right;
593 ptree->right = ttree;
594 reverseParms (ptree->left);
595 reverseParms (ptree->right);
601 /*-----------------------------------------------------------------*/
602 /* processParms - makes sure the parameters are okay and do some */
603 /* processing with them */
604 /*-----------------------------------------------------------------*/
606 processParms (ast * func,
612 sym_link *fetype = func->etype;
614 /* if none of them exist */
615 if (!defParm && !actParm)
619 if (getenv("DEBUG_SANITY")) {
620 fprintf (stderr, "addSym: %s ", defParm->name);
622 /* make sure the type is complete and sane */
623 checkTypeSanity(defParm->etype, defParm->name);
626 /* if the function is being called via a pointer & */
627 /* it has not been defined a reentrant then we cannot */
628 /* have parameters */
629 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
631 werror (W_NONRENT_ARGS);
635 /* if defined parameters ended but actual parameters */
636 /* exist and this is not defined as a variable arg */
637 /* also check if statckAuto option is specified */ // jwk: WHY?
638 if ((!defParm) && actParm && (!func->hasVargs)
639 /* && !options.stackAuto && !IS_RENT (fetype) */)
641 werror (E_TOO_MANY_PARMS);
645 /* if defined parameters present but no actual parameters */
646 if (defParm && !actParm)
648 werror (E_TOO_FEW_PARMS);
652 /* If this is a varargs function... */
653 if (!defParm && actParm && func->hasVargs)
658 if (IS_CAST_OP (actParm)
659 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
661 /* Parameter was explicitly typecast; don't touch it. */
665 /* The ternary ('?') operator is weird: the ftype of the
666 * operator is the type of the condition, but it will return a
667 * (possibly) different type.
669 if (IS_TERNARY_OP(actParm))
671 assert(IS_COLON_OP(actParm->right));
672 assert(actParm->right->left);
673 ftype = actParm->right->left->ftype;
677 ftype = actParm->ftype;
680 /* If it's a small integer, upcast to int. */
681 if (IS_INTEGRAL (ftype)
682 && (getSize (ftype) < (unsigned) INTSIZE))
684 newType = newAst_LINK(INTTYPE);
687 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
689 newType = newAst_LINK (copyLinkChain(ftype));
690 DCL_TYPE (newType->opval.lnk) = GPOINTER;
693 if (IS_AGGREGATE (ftype))
695 newType = newAst_LINK (copyLinkChain (ftype));
696 DCL_TYPE (newType->opval.lnk) = GPOINTER;
700 /* cast required; change this op to a cast. */
701 ast *parmCopy = resolveSymbols (copyAst (actParm));
703 actParm->type = EX_OP;
704 actParm->opval.op = CAST;
705 actParm->left = newType;
706 actParm->right = parmCopy;
707 decorateType (actParm);
709 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
711 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
712 processParms (func, NULL, actParm->right, parmNumber, rightmost));
717 /* if defined parameters ended but actual has not & */
719 if (!defParm && actParm &&
720 (options.stackAuto || IS_RENT (fetype)))
723 resolveSymbols (actParm);
724 /* if this is a PARAM node then match left & right */
725 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
727 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
728 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
732 /* If we have found a value node by following only right-hand links,
733 * then we know that there are no more values after us.
735 * Therefore, if there are more defined parameters, the caller didn't
738 if (rightmost && defParm->next)
740 werror (E_TOO_FEW_PARMS);
746 /* the parameter type must be at least castable */
747 if (compareType (defParm->type, actParm->ftype) == 0) {
748 werror (E_INCOMPAT_TYPES);
749 fprintf (stderr, "type --> '");
750 printTypeChain (actParm->ftype, stderr);
751 fprintf (stderr, "' ");
752 fprintf (stderr, "assigned to type --> '");
753 printTypeChain (defParm->type, stderr);
754 fprintf (stderr, "'\n");
758 /* if the parameter is castable then add the cast */
759 if (compareType (defParm->type, actParm->ftype) < 0)
761 ast *pTree = resolveSymbols (copyAst (actParm));
763 /* now change the current one to a cast */
764 actParm->type = EX_OP;
765 actParm->opval.op = CAST;
766 actParm->left = newAst_LINK (defParm->type);
767 actParm->right = pTree;
768 actParm->etype = defParm->etype;
769 actParm->ftype = defParm->type;
772 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
774 actParm->argSym = defParm->sym;
775 /* make a copy and change the regparm type to the defined parm */
776 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
777 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
781 /*-----------------------------------------------------------------*/
782 /* createIvalType - generates ival for basic types */
783 /*-----------------------------------------------------------------*/
785 createIvalType (ast * sym, sym_link * type, initList * ilist)
789 /* if initList is deep */
790 if (ilist->type == INIT_DEEP)
791 ilist = ilist->init.deep;
793 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
794 return decorateType (newNode ('=', sym, iExpr));
797 /*-----------------------------------------------------------------*/
798 /* createIvalStruct - generates initial value for structures */
799 /*-----------------------------------------------------------------*/
801 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
807 sflds = SPEC_STRUCT (type)->fields;
808 if (ilist->type != INIT_DEEP)
810 werror (E_INIT_STRUCT, "");
814 iloop = ilist->init.deep;
816 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
820 /* if we have come to end */
824 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
825 lAst = decorateType (resolveSymbols (lAst));
826 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
832 /*-----------------------------------------------------------------*/
833 /* createIvalArray - generates code for array initialization */
834 /*-----------------------------------------------------------------*/
836 createIvalArray (ast * sym, sym_link * type, initList * ilist)
840 int lcnt = 0, size = 0;
841 literalList *literalL;
843 /* take care of the special case */
844 /* array of characters can be init */
846 if (IS_CHAR (type->next))
847 if ((rast = createIvalCharPtr (sym,
849 decorateType (resolveSymbols (list2expr (ilist))))))
851 return decorateType (resolveSymbols (rast));
853 /* not the special case */
854 if (ilist->type != INIT_DEEP)
856 werror (E_INIT_STRUCT, "");
860 iloop = ilist->init.deep;
861 lcnt = DCL_ELEM (type);
863 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
867 aSym = decorateType (resolveSymbols(sym));
869 rast = newNode(ARRAYINIT, aSym, NULL);
870 rast->values.constlist = literalL;
872 // Make sure size is set to length of initializer list.
879 if (lcnt && size > lcnt)
881 // Array size was specified, and we have more initializers than needed.
882 char *name=sym->opval.val->sym->name;
883 int lineno=sym->opval.val->sym->lineDef;
885 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
894 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
895 aSym = decorateType (resolveSymbols (aSym));
896 rast = createIval (aSym, type->next, iloop, rast);
897 iloop = (iloop ? iloop->next : NULL);
903 /* no of elements given and we */
904 /* have generated for all of them */
907 // there has to be a better way
908 char *name=sym->opval.val->sym->name;
909 int lineno=sym->opval.val->sym->lineDef;
910 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
917 /* if we have not been given a size */
918 if (!DCL_ELEM (type))
920 DCL_ELEM (type) = size;
923 return decorateType (resolveSymbols (rast));
927 /*-----------------------------------------------------------------*/
928 /* createIvalCharPtr - generates initial values for char pointers */
929 /*-----------------------------------------------------------------*/
931 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
935 /* if this is a pointer & right is a literal array then */
936 /* just assignment will do */
937 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
938 SPEC_SCLS (iexpr->etype) == S_CODE)
939 && IS_ARRAY (iexpr->ftype)))
940 return newNode ('=', sym, iexpr);
942 /* left side is an array so we have to assign each */
944 if ((IS_LITERAL (iexpr->etype) ||
945 SPEC_SCLS (iexpr->etype) == S_CODE)
946 && IS_ARRAY (iexpr->ftype))
948 /* for each character generate an assignment */
949 /* to the array element */
950 char *s = SPEC_CVAL (iexpr->etype).v_char;
955 rast = newNode (NULLOP,
959 newAst_VALUE (valueFromLit ((float) i))),
960 newAst_VALUE (valueFromLit (*s))));
964 rast = newNode (NULLOP,
968 newAst_VALUE (valueFromLit ((float) i))),
969 newAst_VALUE (valueFromLit (*s))));
970 return decorateType (resolveSymbols (rast));
976 /*-----------------------------------------------------------------*/
977 /* createIvalPtr - generates initial value for pointers */
978 /*-----------------------------------------------------------------*/
980 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
986 if (ilist->type == INIT_DEEP)
987 ilist = ilist->init.deep;
989 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
991 /* if character pointer */
992 if (IS_CHAR (type->next))
993 if ((rast = createIvalCharPtr (sym, type, iexpr)))
996 return newNode ('=', sym, iexpr);
999 /*-----------------------------------------------------------------*/
1000 /* createIval - generates code for initial value */
1001 /*-----------------------------------------------------------------*/
1003 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1010 /* if structure then */
1011 if (IS_STRUCT (type))
1012 rast = createIvalStruct (sym, type, ilist);
1014 /* if this is a pointer */
1016 rast = createIvalPtr (sym, type, ilist);
1018 /* if this is an array */
1019 if (IS_ARRAY (type))
1020 rast = createIvalArray (sym, type, ilist);
1022 /* if type is SPECIFIER */
1024 rast = createIvalType (sym, type, ilist);
1027 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1029 return decorateType (resolveSymbols (rast));
1032 /*-----------------------------------------------------------------*/
1033 /* initAggregates - initialises aggregate variables with initv */
1034 /*-----------------------------------------------------------------*/
1036 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1038 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1042 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1044 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1045 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1046 "with -mmcs51 and --model-large");
1050 if (SPEC_OCLS(sym->etype)==xdata &&
1051 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1054 newSym=copySymbol (sym);
1055 SPEC_OCLS(newSym->etype)=code;
1056 sprintf (newSym->name, "%s_init__", sym->name);
1057 sprintf (newSym->rname,"%s_init__", sym->rname);
1058 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1060 // emit it in the static segment
1061 addSet(&statsg->syms, newSym);
1063 // now memcpy() the entire array from cseg
1064 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1065 newAst_VALUE (symbolVal (sym)),
1066 newAst_VALUE (symbolVal (newSym)));
1067 return decorateType(resolveSymbols(ast));
1071 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1074 /*-----------------------------------------------------------------*/
1075 /* gatherAutoInit - creates assignment expressions for initial */
1077 /*-----------------------------------------------------------------*/
1079 gatherAutoInit (symbol * autoChain)
1086 for (sym = autoChain; sym; sym = sym->next)
1089 /* resolve the symbols in the ival */
1091 resolveIvalSym (sym->ival);
1093 /* if this is a static variable & has an */
1094 /* initial value the code needs to be lifted */
1095 /* here to the main portion since they can be */
1096 /* initialised only once at the start */
1097 if (IS_STATIC (sym->etype) && sym->ival &&
1098 SPEC_SCLS (sym->etype) != S_CODE)
1102 // this can only be a constant
1103 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1104 werror (E_CONST_EXPECTED);
1107 /* insert the symbol into the symbol table */
1108 /* with level = 0 & name = rname */
1109 newSym = copySymbol (sym);
1110 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1112 /* now lift the code to main */
1113 if (IS_AGGREGATE (sym->type))
1114 work = initAggregates (sym, sym->ival, NULL);
1116 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1117 list2expr (sym->ival));
1119 setAstLineno (work, sym->lineDef);
1123 staticAutos = newNode (NULLOP, staticAutos, work);
1130 /* if there is an initial value */
1131 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1133 if (IS_AGGREGATE (sym->type))
1134 work = initAggregates (sym, sym->ival, NULL);
1136 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1137 list2expr (sym->ival));
1139 setAstLineno (work, sym->lineDef);
1142 init = newNode (NULLOP, init, work);
1151 /*-----------------------------------------------------------------*/
1152 /* stringToSymbol - creates a symbol from a literal string */
1153 /*-----------------------------------------------------------------*/
1155 stringToSymbol (value * val)
1157 char name[SDCC_NAME_MAX + 1];
1158 static int charLbl = 0;
1161 sprintf (name, "_str_%d", charLbl++);
1162 sym = newSymbol (name, 0); /* make it @ level 0 */
1163 strcpy (sym->rname, name);
1165 /* copy the type from the value passed */
1166 sym->type = copyLinkChain (val->type);
1167 sym->etype = getSpec (sym->type);
1168 /* change to storage class & output class */
1169 SPEC_SCLS (sym->etype) = S_CODE;
1170 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1171 SPEC_STAT (sym->etype) = 1;
1172 /* make the level & block = 0 */
1173 sym->block = sym->level = 0;
1175 /* create an ival */
1176 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1181 allocVariables (sym);
1184 return symbolVal (sym);
1188 /*-----------------------------------------------------------------*/
1189 /* processBlockVars - will go thru the ast looking for block if */
1190 /* a block is found then will allocate the syms */
1191 /* will also gather the auto inits present */
1192 /*-----------------------------------------------------------------*/
1194 processBlockVars (ast * tree, int *stack, int action)
1199 /* if this is a block */
1200 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1204 if (action == ALLOCATE)
1206 *stack += allocVariables (tree->values.sym);
1207 autoInit = gatherAutoInit (tree->values.sym);
1209 /* if there are auto inits then do them */
1211 tree->left = newNode (NULLOP, autoInit, tree->left);
1213 else /* action is deallocate */
1214 deallocLocal (tree->values.sym);
1217 processBlockVars (tree->left, stack, action);
1218 processBlockVars (tree->right, stack, action);
1222 /*-----------------------------------------------------------------*/
1223 /* constExprValue - returns the value of a constant expression */
1224 /* or NULL if it is not a constant expression */
1225 /*-----------------------------------------------------------------*/
1227 constExprValue (ast * cexpr, int check)
1229 cexpr = decorateType (resolveSymbols (cexpr));
1231 /* if this is not a constant then */
1232 if (!IS_LITERAL (cexpr->ftype))
1234 /* then check if this is a literal array
1236 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1237 SPEC_CVAL (cexpr->etype).v_char &&
1238 IS_ARRAY (cexpr->ftype))
1240 value *val = valFromType (cexpr->ftype);
1241 SPEC_SCLS (val->etype) = S_LITERAL;
1242 val->sym = cexpr->opval.val->sym;
1243 val->sym->type = copyLinkChain (cexpr->ftype);
1244 val->sym->etype = getSpec (val->sym->type);
1245 strcpy (val->name, cexpr->opval.val->sym->rname);
1249 /* if we are casting a literal value then */
1250 if (IS_AST_OP (cexpr) &&
1251 cexpr->opval.op == CAST &&
1252 IS_LITERAL (cexpr->left->ftype))
1253 return valCastLiteral (cexpr->ftype,
1254 floatFromVal (cexpr->left->opval.val));
1256 if (IS_AST_VALUE (cexpr))
1257 return cexpr->opval.val;
1260 werror (E_CONST_EXPECTED, "found expression");
1265 /* return the value */
1266 return cexpr->opval.val;
1270 /*-----------------------------------------------------------------*/
1271 /* isLabelInAst - will return true if a given label is found */
1272 /*-----------------------------------------------------------------*/
1274 isLabelInAst (symbol * label, ast * tree)
1276 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1279 if (IS_AST_OP (tree) &&
1280 tree->opval.op == LABEL &&
1281 isSymbolEqual (AST_SYMBOL (tree->left), label))
1284 return isLabelInAst (label, tree->right) &&
1285 isLabelInAst (label, tree->left);
1289 /*-----------------------------------------------------------------*/
1290 /* isLoopCountable - return true if the loop count can be determi- */
1291 /* -ned at compile time . */
1292 /*-----------------------------------------------------------------*/
1294 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1295 symbol ** sym, ast ** init, ast ** end)
1298 /* the loop is considered countable if the following
1299 conditions are true :-
1301 a) initExpr :- <sym> = <const>
1302 b) condExpr :- <sym> < <const1>
1303 c) loopExpr :- <sym> ++
1306 /* first check the initExpr */
1307 if (IS_AST_OP (initExpr) &&
1308 initExpr->opval.op == '=' && /* is assignment */
1309 IS_AST_SYM_VALUE (initExpr->left))
1310 { /* left is a symbol */
1312 *sym = AST_SYMBOL (initExpr->left);
1313 *init = initExpr->right;
1318 /* for now the symbol has to be of
1320 if (!IS_INTEGRAL ((*sym)->type))
1323 /* now check condExpr */
1324 if (IS_AST_OP (condExpr))
1327 switch (condExpr->opval.op)
1330 if (IS_AST_SYM_VALUE (condExpr->left) &&
1331 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1332 IS_AST_LIT_VALUE (condExpr->right))
1334 *end = condExpr->right;
1340 if (IS_AST_OP (condExpr->left) &&
1341 condExpr->left->opval.op == '>' &&
1342 IS_AST_LIT_VALUE (condExpr->left->right) &&
1343 IS_AST_SYM_VALUE (condExpr->left->left) &&
1344 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1347 *end = newNode ('+', condExpr->left->right,
1348 newAst_VALUE (constVal ("1")));
1359 /* check loop expression is of the form <sym>++ */
1360 if (!IS_AST_OP (loopExpr))
1363 /* check if <sym> ++ */
1364 if (loopExpr->opval.op == INC_OP)
1370 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1371 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1378 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1379 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1387 if (loopExpr->opval.op == ADD_ASSIGN)
1390 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1391 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1392 IS_AST_LIT_VALUE (loopExpr->right) &&
1393 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1401 /*-----------------------------------------------------------------*/
1402 /* astHasVolatile - returns true if ast contains any volatile */
1403 /*-----------------------------------------------------------------*/
1405 astHasVolatile (ast * tree)
1410 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1413 if (IS_AST_OP (tree))
1414 return astHasVolatile (tree->left) ||
1415 astHasVolatile (tree->right);
1420 /*-----------------------------------------------------------------*/
1421 /* astHasPointer - return true if the ast contains any ptr variable */
1422 /*-----------------------------------------------------------------*/
1424 astHasPointer (ast * tree)
1429 if (IS_AST_LINK (tree))
1432 /* if we hit an array expression then check
1433 only the left side */
1434 if (IS_AST_OP (tree) && tree->opval.op == '[')
1435 return astHasPointer (tree->left);
1437 if (IS_AST_VALUE (tree))
1438 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1440 return astHasPointer (tree->left) ||
1441 astHasPointer (tree->right);
1445 /*-----------------------------------------------------------------*/
1446 /* astHasSymbol - return true if the ast has the given symbol */
1447 /*-----------------------------------------------------------------*/
1449 astHasSymbol (ast * tree, symbol * sym)
1451 if (!tree || IS_AST_LINK (tree))
1454 if (IS_AST_VALUE (tree))
1456 if (IS_AST_SYM_VALUE (tree))
1457 return isSymbolEqual (AST_SYMBOL (tree), sym);
1462 return astHasSymbol (tree->left, sym) ||
1463 astHasSymbol (tree->right, sym);
1466 /*-----------------------------------------------------------------*/
1467 /* astHasDeref - return true if the ast has an indirect access */
1468 /*-----------------------------------------------------------------*/
1470 astHasDeref (ast * tree)
1472 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1475 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1477 return astHasDeref (tree->left) || astHasDeref (tree->right);
1480 /*-----------------------------------------------------------------*/
1481 /* isConformingBody - the loop body has to conform to a set of rules */
1482 /* for the loop to be considered reversible read on for rules */
1483 /*-----------------------------------------------------------------*/
1485 isConformingBody (ast * pbody, symbol * sym, ast * body)
1488 /* we are going to do a pre-order traversal of the
1489 tree && check for the following conditions. (essentially
1490 a set of very shallow tests )
1491 a) the sym passed does not participate in
1492 any arithmetic operation
1493 b) There are no function calls
1494 c) all jumps are within the body
1495 d) address of loop control variable not taken
1496 e) if an assignment has a pointer on the
1497 left hand side make sure right does not have
1498 loop control variable */
1500 /* if we reach the end or a leaf then true */
1501 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1505 /* if anything else is "volatile" */
1506 if (IS_VOLATILE (TETYPE (pbody)))
1509 /* we will walk the body in a pre-order traversal for
1511 switch (pbody->opval.op)
1513 /*------------------------------------------------------------------*/
1515 return isConformingBody (pbody->right, sym, body);
1517 /*------------------------------------------------------------------*/
1522 /*------------------------------------------------------------------*/
1523 case INC_OP: /* incerement operator unary so left only */
1526 /* sure we are not sym is not modified */
1528 IS_AST_SYM_VALUE (pbody->left) &&
1529 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1533 IS_AST_SYM_VALUE (pbody->right) &&
1534 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1539 /*------------------------------------------------------------------*/
1541 case '*': /* can be unary : if right is null then unary operation */
1546 /* if right is NULL then unary operation */
1547 /*------------------------------------------------------------------*/
1548 /*----------------------------*/
1550 /*----------------------------*/
1553 if (IS_AST_SYM_VALUE (pbody->left) &&
1554 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1557 return isConformingBody (pbody->left, sym, body);
1561 if (astHasSymbol (pbody->left, sym) ||
1562 astHasSymbol (pbody->right, sym))
1567 /*------------------------------------------------------------------*/
1575 if (IS_AST_SYM_VALUE (pbody->left) &&
1576 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1579 if (IS_AST_SYM_VALUE (pbody->right) &&
1580 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1583 return isConformingBody (pbody->left, sym, body) &&
1584 isConformingBody (pbody->right, sym, body);
1591 if (IS_AST_SYM_VALUE (pbody->left) &&
1592 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1594 return isConformingBody (pbody->left, sym, body);
1596 /*------------------------------------------------------------------*/
1608 case SIZEOF: /* evaluate wihout code generation */
1610 return isConformingBody (pbody->left, sym, body) &&
1611 isConformingBody (pbody->right, sym, body);
1613 /*------------------------------------------------------------------*/
1616 /* if left has a pointer & right has loop
1617 control variable then we cannot */
1618 if (astHasPointer (pbody->left) &&
1619 astHasSymbol (pbody->right, sym))
1621 if (astHasVolatile (pbody->left))
1624 if (IS_AST_SYM_VALUE (pbody->left) &&
1625 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1628 if (astHasVolatile (pbody->left))
1631 if (astHasDeref(pbody->right)) return FALSE;
1633 return isConformingBody (pbody->left, sym, body) &&
1634 isConformingBody (pbody->right, sym, body);
1645 assert ("Parser should not have generated this\n");
1647 /*------------------------------------------------------------------*/
1648 /*----------------------------*/
1649 /* comma operator */
1650 /*----------------------------*/
1652 return isConformingBody (pbody->left, sym, body) &&
1653 isConformingBody (pbody->right, sym, body);
1655 /*------------------------------------------------------------------*/
1656 /*----------------------------*/
1658 /*----------------------------*/
1662 /*------------------------------------------------------------------*/
1663 /*----------------------------*/
1664 /* return statement */
1665 /*----------------------------*/
1670 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1675 if (astHasSymbol (pbody->left, sym))
1682 return isConformingBody (pbody->left, sym, body) &&
1683 isConformingBody (pbody->right, sym, body);
1689 /*-----------------------------------------------------------------*/
1690 /* isLoopReversible - takes a for loop as input && returns true */
1691 /* if the for loop is reversible. If yes will set the value of */
1692 /* the loop control var & init value & termination value */
1693 /*-----------------------------------------------------------------*/
1695 isLoopReversible (ast * loop, symbol ** loopCntrl,
1696 ast ** init, ast ** end)
1698 /* if option says don't do it then don't */
1699 if (optimize.noLoopReverse)
1701 /* there are several tests to determine this */
1703 /* for loop has to be of the form
1704 for ( <sym> = <const1> ;
1705 [<sym> < <const2>] ;
1706 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1708 if (!isLoopCountable (AST_FOR (loop, initExpr),
1709 AST_FOR (loop, condExpr),
1710 AST_FOR (loop, loopExpr),
1711 loopCntrl, init, end))
1714 /* now do some serious checking on the body of the loop
1717 return isConformingBody (loop->left, *loopCntrl, loop->left);
1721 /*-----------------------------------------------------------------*/
1722 /* replLoopSym - replace the loop sym by loop sym -1 */
1723 /*-----------------------------------------------------------------*/
1725 replLoopSym (ast * body, symbol * sym)
1728 if (!body || IS_AST_LINK (body))
1731 if (IS_AST_SYM_VALUE (body))
1734 if (isSymbolEqual (AST_SYMBOL (body), sym))
1738 body->opval.op = '-';
1739 body->left = newAst_VALUE (symbolVal (sym));
1740 body->right = newAst_VALUE (constVal ("1"));
1748 replLoopSym (body->left, sym);
1749 replLoopSym (body->right, sym);
1753 /*-----------------------------------------------------------------*/
1754 /* reverseLoop - do the actual loop reversal */
1755 /*-----------------------------------------------------------------*/
1757 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1761 /* create the following tree
1766 if (sym) goto for_continue ;
1769 /* put it together piece by piece */
1770 rloop = newNode (NULLOP,
1771 createIf (newAst_VALUE (symbolVal (sym)),
1773 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1776 newAst_VALUE (symbolVal (sym)),
1779 replLoopSym (loop->left, sym);
1781 rloop = newNode (NULLOP,
1783 newAst_VALUE (symbolVal (sym)),
1784 newNode ('-', end, init)),
1785 createLabel (AST_FOR (loop, continueLabel),
1789 newNode (SUB_ASSIGN,
1790 newAst_VALUE (symbolVal (sym)),
1791 newAst_VALUE (constVal ("1"))),
1794 return decorateType (rloop);
1798 //#define DEMAND_INTEGER_PROMOTION
1800 #ifdef DEMAND_INTEGER_PROMOTION
1802 /*-----------------------------------------------------------------*/
1803 /* walk a tree looking for the leaves. Add a typecast to the given */
1804 /* type to each value leaf node. */
1805 /*-----------------------------------------------------------------*/
1807 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1809 if (!node || IS_CALLOP(node))
1811 /* WTF? We should never get here. */
1815 if (!node->left && !node->right)
1817 /* We're at a leaf; if it's a value, apply the typecast */
1818 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1820 *parentPtr = decorateType (newNode (CAST,
1821 newAst_LINK (copyLinkChain (type)),
1829 pushTypeCastToLeaves (type, node->left, &(node->left));
1833 pushTypeCastToLeaves (type, node->right, &(node->right));
1840 /*-----------------------------------------------------------------*/
1841 /* Given an assignment operation in a tree, determine if the LHS */
1842 /* (the result) has a different (integer) type than the RHS. */
1843 /* If so, walk the RHS and add a typecast to the type of the LHS */
1844 /* to all leaf nodes. */
1845 /*-----------------------------------------------------------------*/
1847 propAsgType (ast * tree)
1849 #ifdef DEMAND_INTEGER_PROMOTION
1850 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1852 /* Nothing to do here... */
1856 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1858 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1865 /*-----------------------------------------------------------------*/
1866 /* decorateType - compute type for this tree also does type cheking */
1867 /* this is done bottom up, since type have to flow upwards */
1868 /* it also does constant folding, and paramater checking */
1869 /*-----------------------------------------------------------------*/
1871 decorateType (ast * tree)
1879 /* if already has type then do nothing */
1880 if (tree->decorated)
1883 tree->decorated = 1;
1885 /* print the line */
1886 /* if not block & function */
1887 if (tree->type == EX_OP &&
1888 (tree->opval.op != FUNCTION &&
1889 tree->opval.op != BLOCK &&
1890 tree->opval.op != NULLOP))
1892 filename = tree->filename;
1893 lineno = tree->lineno;
1896 /* if any child is an error | this one is an error do nothing */
1897 if (tree->isError ||
1898 (tree->left && tree->left->isError) ||
1899 (tree->right && tree->right->isError))
1902 /*------------------------------------------------------------------*/
1903 /*----------------------------*/
1904 /* leaf has been reached */
1905 /*----------------------------*/
1906 /* if this is of type value */
1907 /* just get the type */
1908 if (tree->type == EX_VALUE)
1911 if (IS_LITERAL (tree->opval.val->etype))
1914 /* if this is a character array then declare it */
1915 if (IS_ARRAY (tree->opval.val->type))
1916 tree->opval.val = stringToSymbol (tree->opval.val);
1918 /* otherwise just copy the type information */
1919 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1920 if (funcInChain (tree->opval.val->type))
1922 tree->hasVargs = tree->opval.val->sym->hasVargs;
1923 tree->args = copyValueChain (tree->opval.val->sym->args);
1928 if (tree->opval.val->sym)
1930 /* if the undefined flag is set then give error message */
1931 if (tree->opval.val->sym->undefined)
1933 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1935 TTYPE (tree) = TETYPE (tree) =
1936 tree->opval.val->type = tree->opval.val->sym->type =
1937 tree->opval.val->etype = tree->opval.val->sym->etype =
1938 copyLinkChain (INTTYPE);
1943 /* if impilicit i.e. struct/union member then no type */
1944 if (tree->opval.val->sym->implicit)
1945 TTYPE (tree) = TETYPE (tree) = NULL;
1950 /* else copy the type */
1951 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1953 /* and mark it as referenced */
1954 tree->opval.val->sym->isref = 1;
1955 /* if this is of type function or function pointer */
1956 if (funcInChain (tree->opval.val->type))
1958 tree->hasVargs = tree->opval.val->sym->hasVargs;
1959 tree->args = copyValueChain (tree->opval.val->sym->args);
1969 /* if type link for the case of cast */
1970 if (tree->type == EX_LINK)
1972 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1979 dtl = decorateType (tree->left);
1980 dtr = decorateType (tree->right);
1982 /* this is to take care of situations
1983 when the tree gets rewritten */
1984 if (dtl != tree->left)
1986 if (dtr != tree->right)
1990 /* depending on type of operator do */
1992 switch (tree->opval.op)
1994 /*------------------------------------------------------------------*/
1995 /*----------------------------*/
1997 /*----------------------------*/
2000 /* determine which is the array & which the index */
2001 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2004 ast *tempTree = tree->left;
2005 tree->left = tree->right;
2006 tree->right = tempTree;
2009 /* first check if this is a array or a pointer */
2010 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2012 werror (E_NEED_ARRAY_PTR, "[]");
2013 goto errorTreeReturn;
2016 /* check if the type of the idx */
2017 if (!IS_INTEGRAL (RTYPE (tree)))
2019 werror (E_IDX_NOT_INT);
2020 goto errorTreeReturn;
2023 /* if the left is an rvalue then error */
2026 werror (E_LVALUE_REQUIRED, "array access");
2027 goto errorTreeReturn;
2030 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2031 if (IS_PTR(LTYPE(tree))) {
2032 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2036 /*------------------------------------------------------------------*/
2037 /*----------------------------*/
2039 /*----------------------------*/
2041 /* if this is not a structure */
2042 if (!IS_STRUCT (LTYPE (tree)))
2044 werror (E_STRUCT_UNION, ".");
2045 goto errorTreeReturn;
2047 TTYPE (tree) = structElemType (LTYPE (tree),
2048 (tree->right->type == EX_VALUE ?
2049 tree->right->opval.val : NULL), &tree->args);
2050 TETYPE (tree) = getSpec (TTYPE (tree));
2053 /*------------------------------------------------------------------*/
2054 /*----------------------------*/
2055 /* struct/union pointer */
2056 /*----------------------------*/
2058 /* if not pointer to a structure */
2059 if (!IS_PTR (LTYPE (tree)))
2061 werror (E_PTR_REQD);
2062 goto errorTreeReturn;
2065 if (!IS_STRUCT (LTYPE (tree)->next))
2067 werror (E_STRUCT_UNION, "->");
2068 goto errorTreeReturn;
2071 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2072 (tree->right->type == EX_VALUE ?
2073 tree->right->opval.val : NULL), &tree->args);
2074 TETYPE (tree) = getSpec (TTYPE (tree));
2077 /*------------------------------------------------------------------*/
2078 /*----------------------------*/
2079 /* ++/-- operation */
2080 /*----------------------------*/
2081 case INC_OP: /* incerement operator unary so left only */
2084 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2085 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2086 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2087 werror (E_CODE_WRITE, "++/--");
2096 /*------------------------------------------------------------------*/
2097 /*----------------------------*/
2099 /*----------------------------*/
2100 case '&': /* can be unary */
2101 /* if right is NULL then unary operation */
2102 if (tree->right) /* not an unary operation */
2105 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2107 werror (E_BITWISE_OP);
2108 werror (W_CONTINUE, "left & right types are ");
2109 printTypeChain (LTYPE (tree), stderr);
2110 fprintf (stderr, ",");
2111 printTypeChain (RTYPE (tree), stderr);
2112 fprintf (stderr, "\n");
2113 goto errorTreeReturn;
2116 /* if they are both literal */
2117 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2119 tree->type = EX_VALUE;
2120 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2121 valFromType (RETYPE (tree)), '&');
2123 tree->right = tree->left = NULL;
2124 TETYPE (tree) = tree->opval.val->etype;
2125 TTYPE (tree) = tree->opval.val->type;
2129 /* see if this is a GETHBIT operation if yes
2132 ast *otree = optimizeGetHbit (tree);
2135 return decorateType (otree);
2139 // we can't do this because of "(int & 0xff) << 3"
2141 /* if right or left is literal then result of that type */
2142 if (IS_LITERAL (RTYPE (tree)))
2145 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2146 TETYPE (tree) = getSpec (TTYPE (tree));
2147 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2151 if (IS_LITERAL (LTYPE (tree)))
2153 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2154 TETYPE (tree) = getSpec (TTYPE (tree));
2155 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2161 computeType (LTYPE (tree), RTYPE (tree));
2162 TETYPE (tree) = getSpec (TTYPE (tree));
2167 computeType (LTYPE (tree), RTYPE (tree));
2168 TETYPE (tree) = getSpec (TTYPE (tree));
2170 LRVAL (tree) = RRVAL (tree) = 1;
2174 /*------------------------------------------------------------------*/
2175 /*----------------------------*/
2177 /*----------------------------*/
2179 p->class = DECLARATOR;
2180 /* if bit field then error */
2181 if (IS_BITVAR (tree->left->etype))
2183 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2184 goto errorTreeReturn;
2187 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2189 werror (E_ILLEGAL_ADDR, "address of register variable");
2190 goto errorTreeReturn;
2193 if (IS_FUNC (LTYPE (tree)))
2195 werror (E_ILLEGAL_ADDR, "address of function");
2196 goto errorTreeReturn;
2201 werror (E_LVALUE_REQUIRED, "address of");
2202 goto errorTreeReturn;
2204 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2206 DCL_TYPE (p) = CPOINTER;
2207 DCL_PTR_CONST (p) = port->mem.code_ro;
2209 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2210 DCL_TYPE (p) = FPOINTER;
2211 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2212 DCL_TYPE (p) = PPOINTER;
2213 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2214 DCL_TYPE (p) = IPOINTER;
2215 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2216 DCL_TYPE (p) = EEPPOINTER;
2218 DCL_TYPE (p) = POINTER;
2220 if (IS_AST_SYM_VALUE (tree->left))
2222 AST_SYMBOL (tree->left)->addrtaken = 1;
2223 AST_SYMBOL (tree->left)->allocreq = 1;
2226 p->next = LTYPE (tree);
2228 TETYPE (tree) = getSpec (TTYPE (tree));
2229 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2230 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2235 /*------------------------------------------------------------------*/
2236 /*----------------------------*/
2238 /*----------------------------*/
2240 /* if the rewrite succeeds then don't go any furthur */
2242 ast *wtree = optimizeRRCRLC (tree);
2244 return decorateType (wtree);
2246 /*------------------------------------------------------------------*/
2247 /*----------------------------*/
2249 /*----------------------------*/
2251 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2253 werror (E_BITWISE_OP);
2254 werror (W_CONTINUE, "left & right types are ");
2255 printTypeChain (LTYPE (tree), stderr);
2256 fprintf (stderr, ",");
2257 printTypeChain (RTYPE (tree), stderr);
2258 fprintf (stderr, "\n");
2259 goto errorTreeReturn;
2262 /* if they are both literal then */
2263 /* rewrite the tree */
2264 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2266 tree->type = EX_VALUE;
2267 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2268 valFromType (RETYPE (tree)),
2270 tree->right = tree->left = NULL;
2271 TETYPE (tree) = tree->opval.val->etype;
2272 TTYPE (tree) = tree->opval.val->type;
2275 LRVAL (tree) = RRVAL (tree) = 1;
2276 TETYPE (tree) = getSpec (TTYPE (tree) =
2277 computeType (LTYPE (tree),
2280 /*------------------------------------------------------------------*/
2281 /*----------------------------*/
2283 /*----------------------------*/
2285 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2287 werror (E_INVALID_OP, "divide");
2288 goto errorTreeReturn;
2290 /* if they are both literal then */
2291 /* rewrite the tree */
2292 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2294 tree->type = EX_VALUE;
2295 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2296 valFromType (RETYPE (tree)));
2297 tree->right = tree->left = NULL;
2298 TETYPE (tree) = getSpec (TTYPE (tree) =
2299 tree->opval.val->type);
2302 LRVAL (tree) = RRVAL (tree) = 1;
2303 TETYPE (tree) = getSpec (TTYPE (tree) =
2304 computeType (LTYPE (tree),
2308 /*------------------------------------------------------------------*/
2309 /*----------------------------*/
2311 /*----------------------------*/
2313 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2315 werror (E_BITWISE_OP);
2316 werror (W_CONTINUE, "left & right types are ");
2317 printTypeChain (LTYPE (tree), stderr);
2318 fprintf (stderr, ",");
2319 printTypeChain (RTYPE (tree), stderr);
2320 fprintf (stderr, "\n");
2321 goto errorTreeReturn;
2323 /* if they are both literal then */
2324 /* rewrite the tree */
2325 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2327 tree->type = EX_VALUE;
2328 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2329 valFromType (RETYPE (tree)));
2330 tree->right = tree->left = NULL;
2331 TETYPE (tree) = getSpec (TTYPE (tree) =
2332 tree->opval.val->type);
2335 LRVAL (tree) = RRVAL (tree) = 1;
2336 TETYPE (tree) = getSpec (TTYPE (tree) =
2337 computeType (LTYPE (tree),
2341 /*------------------------------------------------------------------*/
2342 /*----------------------------*/
2343 /* address dereference */
2344 /*----------------------------*/
2345 case '*': /* can be unary : if right is null then unary operation */
2348 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2350 werror (E_PTR_REQD);
2351 goto errorTreeReturn;
2356 werror (E_LVALUE_REQUIRED, "pointer deref");
2357 goto errorTreeReturn;
2359 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2360 LTYPE (tree)->next : NULL);
2361 TETYPE (tree) = getSpec (TTYPE (tree));
2362 tree->args = tree->left->args;
2363 tree->hasVargs = tree->left->hasVargs;
2364 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2368 /*------------------------------------------------------------------*/
2369 /*----------------------------*/
2370 /* multiplication */
2371 /*----------------------------*/
2372 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2374 werror (E_INVALID_OP, "multiplication");
2375 goto errorTreeReturn;
2378 /* if they are both literal then */
2379 /* rewrite the tree */
2380 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2382 tree->type = EX_VALUE;
2383 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2384 valFromType (RETYPE (tree)));
2385 tree->right = tree->left = NULL;
2386 TETYPE (tree) = getSpec (TTYPE (tree) =
2387 tree->opval.val->type);
2391 /* if left is a literal exchange left & right */
2392 if (IS_LITERAL (LTYPE (tree)))
2394 ast *tTree = tree->left;
2395 tree->left = tree->right;
2396 tree->right = tTree;
2399 LRVAL (tree) = RRVAL (tree) = 1;
2400 /* promote result to int if left & right are char
2401 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2402 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2403 TETYPE (tree) = getSpec (TTYPE (tree) =
2404 computeType (LTYPE (tree),
2406 SPEC_NOUN(TETYPE(tree)) = V_INT;
2408 TETYPE (tree) = getSpec (TTYPE (tree) =
2409 computeType (LTYPE (tree),
2414 /*------------------------------------------------------------------*/
2415 /*----------------------------*/
2416 /* unary '+' operator */
2417 /*----------------------------*/
2422 if (!IS_INTEGRAL (LTYPE (tree)))
2424 werror (E_UNARY_OP, '+');
2425 goto errorTreeReturn;
2428 /* if left is a literal then do it */
2429 if (IS_LITERAL (LTYPE (tree)))
2431 tree->type = EX_VALUE;
2432 tree->opval.val = valFromType (LETYPE (tree));
2434 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2438 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2442 /*------------------------------------------------------------------*/
2443 /*----------------------------*/
2445 /*----------------------------*/
2447 /* this is not a unary operation */
2448 /* if both pointers then problem */
2449 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2450 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2452 werror (E_PTR_PLUS_PTR);
2453 goto errorTreeReturn;
2456 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2457 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2459 werror (E_PLUS_INVALID, "+");
2460 goto errorTreeReturn;
2463 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2464 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2466 werror (E_PLUS_INVALID, "+");
2467 goto errorTreeReturn;
2469 /* if they are both literal then */
2470 /* rewrite the tree */
2471 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2473 tree->type = EX_VALUE;
2474 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2475 valFromType (RETYPE (tree)));
2476 tree->right = tree->left = NULL;
2477 TETYPE (tree) = getSpec (TTYPE (tree) =
2478 tree->opval.val->type);
2482 /* if the right is a pointer or left is a literal
2483 xchange left & right */
2484 if (IS_ARRAY (RTYPE (tree)) ||
2485 IS_PTR (RTYPE (tree)) ||
2486 IS_LITERAL (LTYPE (tree)))
2488 ast *tTree = tree->left;
2489 tree->left = tree->right;
2490 tree->right = tTree;
2493 LRVAL (tree) = RRVAL (tree) = 1;
2494 /* if the left is a pointer */
2495 if (IS_PTR (LTYPE (tree)))
2496 TETYPE (tree) = getSpec (TTYPE (tree) =
2499 TETYPE (tree) = getSpec (TTYPE (tree) =
2500 computeType (LTYPE (tree),
2504 /*------------------------------------------------------------------*/
2505 /*----------------------------*/
2507 /*----------------------------*/
2508 case '-': /* can be unary */
2509 /* if right is null then unary */
2513 if (!IS_ARITHMETIC (LTYPE (tree)))
2515 werror (E_UNARY_OP, tree->opval.op);
2516 goto errorTreeReturn;
2519 /* if left is a literal then do it */
2520 if (IS_LITERAL (LTYPE (tree)))
2522 tree->type = EX_VALUE;
2523 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2525 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2526 SPEC_USIGN(TETYPE(tree)) = 0;
2530 TTYPE (tree) = LTYPE (tree);
2534 /*------------------------------------------------------------------*/
2535 /*----------------------------*/
2537 /*----------------------------*/
2539 if (!(IS_PTR (LTYPE (tree)) ||
2540 IS_ARRAY (LTYPE (tree)) ||
2541 IS_ARITHMETIC (LTYPE (tree))))
2543 werror (E_PLUS_INVALID, "-");
2544 goto errorTreeReturn;
2547 if (!(IS_PTR (RTYPE (tree)) ||
2548 IS_ARRAY (RTYPE (tree)) ||
2549 IS_ARITHMETIC (RTYPE (tree))))
2551 werror (E_PLUS_INVALID, "-");
2552 goto errorTreeReturn;
2555 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2556 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2557 IS_INTEGRAL (RTYPE (tree))))
2559 werror (E_PLUS_INVALID, "-");
2560 goto errorTreeReturn;
2563 /* if they are both literal then */
2564 /* rewrite the tree */
2565 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2567 tree->type = EX_VALUE;
2568 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2569 valFromType (RETYPE (tree)));
2570 tree->right = tree->left = NULL;
2571 TETYPE (tree) = getSpec (TTYPE (tree) =
2572 tree->opval.val->type);
2576 /* if the left & right are equal then zero */
2577 if (isAstEqual (tree->left, tree->right))
2579 tree->type = EX_VALUE;
2580 tree->left = tree->right = NULL;
2581 tree->opval.val = constVal ("0");
2582 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2586 /* if both of them are pointers or arrays then */
2587 /* the result is going to be an integer */
2588 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2589 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2590 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2592 /* if only the left is a pointer */
2593 /* then result is a pointer */
2594 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2595 TETYPE (tree) = getSpec (TTYPE (tree) =
2598 TETYPE (tree) = getSpec (TTYPE (tree) =
2599 computeType (LTYPE (tree),
2601 LRVAL (tree) = RRVAL (tree) = 1;
2604 /*------------------------------------------------------------------*/
2605 /*----------------------------*/
2607 /*----------------------------*/
2609 /* can be only integral type */
2610 if (!IS_INTEGRAL (LTYPE (tree)))
2612 werror (E_UNARY_OP, tree->opval.op);
2613 goto errorTreeReturn;
2616 /* if left is a literal then do it */
2617 if (IS_LITERAL (LTYPE (tree)))
2619 tree->type = EX_VALUE;
2620 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2622 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2626 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2629 /*------------------------------------------------------------------*/
2630 /*----------------------------*/
2632 /*----------------------------*/
2634 /* can be pointer */
2635 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2636 !IS_PTR (LTYPE (tree)) &&
2637 !IS_ARRAY (LTYPE (tree)))
2639 werror (E_UNARY_OP, tree->opval.op);
2640 goto errorTreeReturn;
2643 /* if left is a literal then do it */
2644 if (IS_LITERAL (LTYPE (tree)))
2646 tree->type = EX_VALUE;
2647 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2649 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2653 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2656 /*------------------------------------------------------------------*/
2657 /*----------------------------*/
2659 /*----------------------------*/
2662 TTYPE (tree) = LTYPE (tree);
2663 TETYPE (tree) = LETYPE (tree);
2667 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2672 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2674 werror (E_SHIFT_OP_INVALID);
2675 werror (W_CONTINUE, "left & right types are ");
2676 printTypeChain (LTYPE (tree), stderr);
2677 fprintf (stderr, ",");
2678 printTypeChain (RTYPE (tree), stderr);
2679 fprintf (stderr, "\n");
2680 goto errorTreeReturn;
2683 /* if they are both literal then */
2684 /* rewrite the tree */
2685 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2687 tree->type = EX_VALUE;
2688 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2689 valFromType (RETYPE (tree)),
2690 (tree->opval.op == LEFT_OP ? 1 : 0));
2691 tree->right = tree->left = NULL;
2692 TETYPE (tree) = getSpec (TTYPE (tree) =
2693 tree->opval.val->type);
2696 /* if only the right side is a literal & we are
2697 shifting more than size of the left operand then zero */
2698 if (IS_LITERAL (RTYPE (tree)) &&
2699 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2700 (getSize (LTYPE (tree)) * 8))
2702 werror (W_SHIFT_CHANGED,
2703 (tree->opval.op == LEFT_OP ? "left" : "right"));
2704 tree->type = EX_VALUE;
2705 tree->left = tree->right = NULL;
2706 tree->opval.val = constVal ("0");
2707 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2710 LRVAL (tree) = RRVAL (tree) = 1;
2711 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2713 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2717 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2721 /*------------------------------------------------------------------*/
2722 /*----------------------------*/
2724 /*----------------------------*/
2725 case CAST: /* change the type */
2726 /* cannot cast to an aggregate type */
2727 if (IS_AGGREGATE (LTYPE (tree)))
2729 werror (E_CAST_ILLEGAL);
2730 goto errorTreeReturn;
2733 /* make sure the type is complete and sane */
2734 checkTypeSanity(LETYPE(tree), "(cast)");
2737 /* if the right is a literal replace the tree */
2738 if (IS_LITERAL (RETYPE (tree))) {
2739 if (!IS_PTR (LTYPE (tree))) {
2740 tree->type = EX_VALUE;
2742 valCastLiteral (LTYPE (tree),
2743 floatFromVal (valFromType (RETYPE (tree))));
2746 TTYPE (tree) = tree->opval.val->type;
2747 tree->values.literalFromCast = 1;
2748 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2749 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2750 sym_link *rest = LTYPE(tree)->next;
2751 werror(W_LITERAL_GENERIC);
2752 TTYPE(tree) = newLink();
2753 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2754 TTYPE(tree)->next = rest;
2755 tree->left->opval.lnk = TTYPE(tree);
2758 TTYPE (tree) = LTYPE (tree);
2762 TTYPE (tree) = LTYPE (tree);
2766 /* if the right is a literal replace the tree */
2767 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2768 tree->type = EX_VALUE;
2770 valCastLiteral (LTYPE (tree),
2771 floatFromVal (valFromType (RETYPE (tree))));
2774 TTYPE (tree) = tree->opval.val->type;
2775 tree->values.literalFromCast = 1;
2777 TTYPE (tree) = LTYPE (tree);
2782 TETYPE (tree) = getSpec (TTYPE (tree));
2786 /*------------------------------------------------------------------*/
2787 /*----------------------------*/
2788 /* logical &&, || */
2789 /*----------------------------*/
2792 /* each must me arithmetic type or be a pointer */
2793 if (!IS_PTR (LTYPE (tree)) &&
2794 !IS_ARRAY (LTYPE (tree)) &&
2795 !IS_INTEGRAL (LTYPE (tree)))
2797 werror (E_COMPARE_OP);
2798 goto errorTreeReturn;
2801 if (!IS_PTR (RTYPE (tree)) &&
2802 !IS_ARRAY (RTYPE (tree)) &&
2803 !IS_INTEGRAL (RTYPE (tree)))
2805 werror (E_COMPARE_OP);
2806 goto errorTreeReturn;
2808 /* if they are both literal then */
2809 /* rewrite the tree */
2810 if (IS_LITERAL (RTYPE (tree)) &&
2811 IS_LITERAL (LTYPE (tree)))
2813 tree->type = EX_VALUE;
2814 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2815 valFromType (RETYPE (tree)),
2817 tree->right = tree->left = NULL;
2818 TETYPE (tree) = getSpec (TTYPE (tree) =
2819 tree->opval.val->type);
2822 LRVAL (tree) = RRVAL (tree) = 1;
2823 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2826 /*------------------------------------------------------------------*/
2827 /*----------------------------*/
2828 /* comparison operators */
2829 /*----------------------------*/
2837 ast *lt = optimizeCompare (tree);
2843 /* if they are pointers they must be castable */
2844 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2846 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2848 werror (E_COMPARE_OP);
2849 fprintf (stderr, "comparing type ");
2850 printTypeChain (LTYPE (tree), stderr);
2851 fprintf (stderr, "to type ");
2852 printTypeChain (RTYPE (tree), stderr);
2853 fprintf (stderr, "\n");
2854 goto errorTreeReturn;
2857 /* else they should be promotable to one another */
2860 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2861 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2863 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2865 werror (E_COMPARE_OP);
2866 fprintf (stderr, "comparing type ");
2867 printTypeChain (LTYPE (tree), stderr);
2868 fprintf (stderr, "to type ");
2869 printTypeChain (RTYPE (tree), stderr);
2870 fprintf (stderr, "\n");
2871 goto errorTreeReturn;
2875 /* if they are both literal then */
2876 /* rewrite the tree */
2877 if (IS_LITERAL (RTYPE (tree)) &&
2878 IS_LITERAL (LTYPE (tree)))
2880 tree->type = EX_VALUE;
2881 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2882 valFromType (RETYPE (tree)),
2884 tree->right = tree->left = NULL;
2885 TETYPE (tree) = getSpec (TTYPE (tree) =
2886 tree->opval.val->type);
2889 LRVAL (tree) = RRVAL (tree) = 1;
2890 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2893 /*------------------------------------------------------------------*/
2894 /*----------------------------*/
2896 /*----------------------------*/
2897 case SIZEOF: /* evaluate wihout code generation */
2898 /* change the type to a integer */
2899 tree->type = EX_VALUE;
2900 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2901 tree->opval.val = constVal (buffer);
2902 tree->right = tree->left = NULL;
2903 TETYPE (tree) = getSpec (TTYPE (tree) =
2904 tree->opval.val->type);
2907 /*------------------------------------------------------------------*/
2908 /*----------------------------*/
2909 /* conditional operator '?' */
2910 /*----------------------------*/
2912 /* the type is value of the colon operator (on the right) */
2913 assert(IS_COLON_OP(tree->right));
2914 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2915 TETYPE (tree) = getSpec (TTYPE (tree));
2919 /* if they don't match we have a problem */
2920 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2922 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2923 goto errorTreeReturn;
2926 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2927 TETYPE (tree) = getSpec (TTYPE (tree));
2931 /*------------------------------------------------------------------*/
2932 /*----------------------------*/
2933 /* assignment operators */
2934 /*----------------------------*/
2937 /* for these it must be both must be integral */
2938 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2939 !IS_ARITHMETIC (RTYPE (tree)))
2941 werror (E_OPS_INTEGRAL);
2942 goto errorTreeReturn;
2945 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2947 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2948 werror (E_CODE_WRITE, " ");
2952 werror (E_LVALUE_REQUIRED, "*= or /=");
2953 goto errorTreeReturn;
2966 /* for these it must be both must be integral */
2967 if (!IS_INTEGRAL (LTYPE (tree)) ||
2968 !IS_INTEGRAL (RTYPE (tree)))
2970 werror (E_OPS_INTEGRAL);
2971 goto errorTreeReturn;
2974 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2976 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2977 werror (E_CODE_WRITE, " ");
2981 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2982 goto errorTreeReturn;
2990 /*------------------------------------------------------------------*/
2991 /*----------------------------*/
2993 /*----------------------------*/
2995 if (!(IS_PTR (LTYPE (tree)) ||
2996 IS_ARITHMETIC (LTYPE (tree))))
2998 werror (E_PLUS_INVALID, "-=");
2999 goto errorTreeReturn;
3002 if (!(IS_PTR (RTYPE (tree)) ||
3003 IS_ARITHMETIC (RTYPE (tree))))
3005 werror (E_PLUS_INVALID, "-=");
3006 goto errorTreeReturn;
3009 TETYPE (tree) = getSpec (TTYPE (tree) =
3010 computeType (LTYPE (tree),
3013 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3014 werror (E_CODE_WRITE, " ");
3018 werror (E_LVALUE_REQUIRED, "-=");
3019 goto errorTreeReturn;
3027 /*------------------------------------------------------------------*/
3028 /*----------------------------*/
3030 /*----------------------------*/
3032 /* this is not a unary operation */
3033 /* if both pointers then problem */
3034 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3036 werror (E_PTR_PLUS_PTR);
3037 goto errorTreeReturn;
3040 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3042 werror (E_PLUS_INVALID, "+=");
3043 goto errorTreeReturn;
3046 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3048 werror (E_PLUS_INVALID, "+=");
3049 goto errorTreeReturn;
3052 TETYPE (tree) = getSpec (TTYPE (tree) =
3053 computeType (LTYPE (tree),
3056 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3057 werror (E_CODE_WRITE, " ");
3061 werror (E_LVALUE_REQUIRED, "+=");
3062 goto errorTreeReturn;
3065 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3066 tree->opval.op = '=';
3072 /*------------------------------------------------------------------*/
3073 /*----------------------------*/
3074 /* straight assignemnt */
3075 /*----------------------------*/
3077 /* cannot be an aggregate */
3078 if (IS_AGGREGATE (LTYPE (tree)))
3080 werror (E_AGGR_ASSIGN);
3081 goto errorTreeReturn;
3084 /* they should either match or be castable */
3085 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3087 werror (E_TYPE_MISMATCH, "assignment", " ");
3088 fprintf (stderr, "type --> '");
3089 printTypeChain (RTYPE (tree), stderr);
3090 fprintf (stderr, "' ");
3091 fprintf (stderr, "assigned to type --> '");
3092 printTypeChain (LTYPE (tree), stderr);
3093 fprintf (stderr, "'\n");
3094 goto errorTreeReturn;
3097 /* if the left side of the tree is of type void
3098 then report error */
3099 if (IS_VOID (LTYPE (tree)))
3101 werror (E_CAST_ZERO);
3102 fprintf (stderr, "type --> '");
3103 printTypeChain (RTYPE (tree), stderr);
3104 fprintf (stderr, "' ");
3105 fprintf (stderr, "assigned to type --> '");
3106 printTypeChain (LTYPE (tree), stderr);
3107 fprintf (stderr, "'\n");
3110 TETYPE (tree) = getSpec (TTYPE (tree) =
3114 if (!tree->initMode ) {
3115 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3116 werror (E_CODE_WRITE, " ");
3120 werror (E_LVALUE_REQUIRED, "=");
3121 goto errorTreeReturn;
3128 /*------------------------------------------------------------------*/
3129 /*----------------------------*/
3130 /* comma operator */
3131 /*----------------------------*/
3133 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3136 /*------------------------------------------------------------------*/
3137 /*----------------------------*/
3139 /*----------------------------*/
3143 if (processParms (tree->left,
3145 tree->right, &parmNumber, TRUE))
3146 goto errorTreeReturn;
3148 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3150 tree->left->args = reverseVal (tree->left->args);
3151 reverseParms (tree->right);
3154 tree->args = tree->left->args;
3155 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3158 /*------------------------------------------------------------------*/
3159 /*----------------------------*/
3160 /* return statement */
3161 /*----------------------------*/
3166 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3168 werror (W_RETURN_MISMATCH);
3169 goto errorTreeReturn;
3172 if (IS_VOID (currFunc->type->next)
3174 !IS_VOID (RTYPE (tree)))
3176 werror (E_FUNC_VOID);
3177 goto errorTreeReturn;
3180 /* if there is going to be a casing required then add it */
3181 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3183 #if 0 && defined DEMAND_INTEGER_PROMOTION
3184 if (IS_INTEGRAL (currFunc->type->next))
3186 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3192 decorateType (newNode (CAST,
3193 newAst_LINK (copyLinkChain (currFunc->type->next)),
3203 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3205 werror (E_VOID_FUNC, currFunc->name);
3206 goto errorTreeReturn;
3209 TTYPE (tree) = TETYPE (tree) = NULL;
3212 /*------------------------------------------------------------------*/
3213 /*----------------------------*/
3214 /* switch statement */
3215 /*----------------------------*/
3217 /* the switch value must be an integer */
3218 if (!IS_INTEGRAL (LTYPE (tree)))
3220 werror (E_SWITCH_NON_INTEGER);
3221 goto errorTreeReturn;
3224 TTYPE (tree) = TETYPE (tree) = NULL;
3227 /*------------------------------------------------------------------*/
3228 /*----------------------------*/
3230 /*----------------------------*/
3232 tree->left = backPatchLabels (tree->left,
3235 TTYPE (tree) = TETYPE (tree) = NULL;
3238 /*------------------------------------------------------------------*/
3239 /*----------------------------*/
3241 /*----------------------------*/
3244 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3245 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3246 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3248 /* if the for loop is reversible then
3249 reverse it otherwise do what we normally
3255 if (isLoopReversible (tree, &sym, &init, &end))
3256 return reverseLoop (tree, sym, init, end);
3258 return decorateType (createFor (AST_FOR (tree, trueLabel),
3259 AST_FOR (tree, continueLabel),
3260 AST_FOR (tree, falseLabel),
3261 AST_FOR (tree, condLabel),
3262 AST_FOR (tree, initExpr),
3263 AST_FOR (tree, condExpr),
3264 AST_FOR (tree, loopExpr),
3268 TTYPE (tree) = TETYPE (tree) = NULL;
3272 /* some error found this tree will be killed */
3274 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3275 tree->opval.op = NULLOP;
3281 /*-----------------------------------------------------------------*/
3282 /* sizeofOp - processes size of operation */
3283 /*-----------------------------------------------------------------*/
3285 sizeofOp (sym_link * type)
3289 /* make sure the type is complete and sane */
3290 checkTypeSanity(type, "(sizeof)");
3292 /* get the size and convert it to character */
3293 sprintf (buff, "%d", getSize (type));
3295 /* now convert into value */
3296 return constVal (buff);
3300 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3301 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3302 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3303 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3304 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3305 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3306 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3308 /*-----------------------------------------------------------------*/
3309 /* backPatchLabels - change and or not operators to flow control */
3310 /*-----------------------------------------------------------------*/
3312 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3318 if (!(IS_ANDORNOT (tree)))
3321 /* if this an and */
3324 static int localLbl = 0;
3327 sprintf (buffer, "_and_%d", localLbl++);
3328 localLabel = newSymbol (buffer, NestLevel);
3330 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3332 /* if left is already a IFX then just change the if true label in that */
3333 if (!IS_IFX (tree->left))
3334 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3336 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3337 /* right is a IFX then just join */
3338 if (IS_IFX (tree->right))
3339 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3341 tree->right = createLabel (localLabel, tree->right);
3342 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3344 return newNode (NULLOP, tree->left, tree->right);
3347 /* if this is an or operation */
3350 static int localLbl = 0;
3353 sprintf (buffer, "_or_%d", localLbl++);
3354 localLabel = newSymbol (buffer, NestLevel);
3356 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3358 /* if left is already a IFX then just change the if true label in that */
3359 if (!IS_IFX (tree->left))
3360 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3362 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3363 /* right is a IFX then just join */
3364 if (IS_IFX (tree->right))
3365 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3367 tree->right = createLabel (localLabel, tree->right);
3368 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3370 return newNode (NULLOP, tree->left, tree->right);
3376 int wasnot = IS_NOT (tree->left);
3377 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3379 /* if the left is already a IFX */
3380 if (!IS_IFX (tree->left))
3381 tree->left = newNode (IFX, tree->left, NULL);
3385 tree->left->trueLabel = trueLabel;
3386 tree->left->falseLabel = falseLabel;
3390 tree->left->trueLabel = falseLabel;
3391 tree->left->falseLabel = trueLabel;
3398 tree->trueLabel = trueLabel;
3399 tree->falseLabel = falseLabel;
3406 /*-----------------------------------------------------------------*/
3407 /* createBlock - create expression tree for block */
3408 /*-----------------------------------------------------------------*/
3410 createBlock (symbol * decl, ast * body)
3414 /* if the block has nothing */
3418 ex = newNode (BLOCK, NULL, body);
3419 ex->values.sym = decl;
3421 ex->right = ex->right;
3427 /*-----------------------------------------------------------------*/
3428 /* createLabel - creates the expression tree for labels */
3429 /*-----------------------------------------------------------------*/
3431 createLabel (symbol * label, ast * stmnt)
3434 char name[SDCC_NAME_MAX + 1];
3437 /* must create fresh symbol if the symbol name */
3438 /* exists in the symbol table, since there can */
3439 /* be a variable with the same name as the labl */
3440 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3441 (csym->level == label->level))
3442 label = newSymbol (label->name, label->level);
3444 /* change the name before putting it in add _ */
3445 sprintf (name, "%s", label->name);
3447 /* put the label in the LabelSymbol table */
3448 /* but first check if a label of the same */
3450 if ((csym = findSym (LabelTab, NULL, name)))
3451 werror (E_DUPLICATE_LABEL, label->name);
3453 addSym (LabelTab, label, name, label->level, 0, 0);
3456 label->key = labelKey++;
3457 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3463 /*-----------------------------------------------------------------*/
3464 /* createCase - generates the parsetree for a case statement */
3465 /*-----------------------------------------------------------------*/
3467 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3469 char caseLbl[SDCC_NAME_MAX + 1];
3473 /* if the switch statement does not exist */
3474 /* then case is out of context */
3477 werror (E_CASE_CONTEXT);
3481 caseVal = decorateType (resolveSymbols (caseVal));
3482 /* if not a constant then error */
3483 if (!IS_LITERAL (caseVal->ftype))
3485 werror (E_CASE_CONSTANT);
3489 /* if not a integer than error */
3490 if (!IS_INTEGRAL (caseVal->ftype))
3492 werror (E_CASE_NON_INTEGER);
3496 /* find the end of the switch values chain */
3497 if (!(val = swStat->values.switchVals.swVals))
3498 swStat->values.switchVals.swVals = caseVal->opval.val;
3501 /* also order the cases according to value */
3503 int cVal = (int) floatFromVal (caseVal->opval.val);
3504 while (val && (int) floatFromVal (val) < cVal)
3510 /* if we reached the end then */
3513 pval->next = caseVal->opval.val;
3517 /* we found a value greater than */
3518 /* the current value we must add this */
3519 /* before the value */
3520 caseVal->opval.val->next = val;
3522 /* if this was the first in chain */
3523 if (swStat->values.switchVals.swVals == val)
3524 swStat->values.switchVals.swVals =
3527 pval->next = caseVal->opval.val;
3532 /* create the case label */
3533 sprintf (caseLbl, "_case_%d_%d",
3534 swStat->values.switchVals.swNum,
3535 (int) floatFromVal (caseVal->opval.val));
3537 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3542 /*-----------------------------------------------------------------*/
3543 /* createDefault - creates the parse tree for the default statement */
3544 /*-----------------------------------------------------------------*/
3546 createDefault (ast * swStat, ast * stmnt)
3548 char defLbl[SDCC_NAME_MAX + 1];
3550 /* if the switch statement does not exist */
3551 /* then case is out of context */
3554 werror (E_CASE_CONTEXT);
3558 /* turn on the default flag */
3559 swStat->values.switchVals.swDefault = 1;
3561 /* create the label */
3562 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3563 return createLabel (newSymbol (defLbl, 0), stmnt);
3566 /*-----------------------------------------------------------------*/
3567 /* createIf - creates the parsetree for the if statement */
3568 /*-----------------------------------------------------------------*/
3570 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3572 static int Lblnum = 0;
3574 symbol *ifTrue, *ifFalse, *ifEnd;
3576 /* if neither exists */
3577 if (!elseBody && !ifBody)
3580 /* create the labels */
3581 sprintf (buffer, "_iffalse_%d", Lblnum);
3582 ifFalse = newSymbol (buffer, NestLevel);
3583 /* if no else body then end == false */
3588 sprintf (buffer, "_ifend_%d", Lblnum);
3589 ifEnd = newSymbol (buffer, NestLevel);
3592 sprintf (buffer, "_iftrue_%d", Lblnum);
3593 ifTrue = newSymbol (buffer, NestLevel);
3597 /* attach the ifTrue label to the top of it body */
3598 ifBody = createLabel (ifTrue, ifBody);
3599 /* attach a goto end to the ifBody if else is present */
3602 ifBody = newNode (NULLOP, ifBody,
3604 newAst_VALUE (symbolVal (ifEnd)),
3606 /* put the elseLabel on the else body */
3607 elseBody = createLabel (ifFalse, elseBody);
3608 /* out the end at the end of the body */
3609 elseBody = newNode (NULLOP,
3611 createLabel (ifEnd, NULL));
3615 ifBody = newNode (NULLOP, ifBody,
3616 createLabel (ifFalse, NULL));
3618 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3619 if (IS_IFX (condAst))
3622 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3624 return newNode (NULLOP, ifTree,
3625 newNode (NULLOP, ifBody, elseBody));
3629 /*-----------------------------------------------------------------*/
3630 /* createDo - creates parse tree for do */
3633 /* _docontinue_n: */
3634 /* condition_expression +-> trueLabel -> _dobody_n */
3636 /* +-> falseLabel-> _dobreak_n */
3638 /*-----------------------------------------------------------------*/
3640 createDo (symbol * trueLabel, symbol * continueLabel,
3641 symbol * falseLabel, ast * condAst, ast * doBody)
3646 /* if the body does not exist then it is simple */
3649 condAst = backPatchLabels (condAst, continueLabel, NULL);
3650 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3651 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3652 doTree->trueLabel = continueLabel;
3653 doTree->falseLabel = NULL;
3657 /* otherwise we have a body */
3658 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3660 /* attach the body label to the top */
3661 doBody = createLabel (trueLabel, doBody);
3662 /* attach the continue label to end of body */
3663 doBody = newNode (NULLOP, doBody,
3664 createLabel (continueLabel, NULL));
3666 /* now put the break label at the end */
3667 if (IS_IFX (condAst))
3670 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3672 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3674 /* putting it together */
3675 return newNode (NULLOP, doBody, doTree);
3678 /*-----------------------------------------------------------------*/
3679 /* createFor - creates parse tree for 'for' statement */
3682 /* condExpr +-> trueLabel -> _forbody_n */
3684 /* +-> falseLabel-> _forbreak_n */
3687 /* _forcontinue_n: */
3689 /* goto _forcond_n ; */
3691 /*-----------------------------------------------------------------*/
3693 createFor (symbol * trueLabel, symbol * continueLabel,
3694 symbol * falseLabel, symbol * condLabel,
3695 ast * initExpr, ast * condExpr, ast * loopExpr,
3700 /* if loopexpression not present then we can generate it */
3701 /* the same way as a while */
3703 return newNode (NULLOP, initExpr,
3704 createWhile (trueLabel, continueLabel,
3705 falseLabel, condExpr, forBody));
3706 /* vanilla for statement */
3707 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3709 if (condExpr && !IS_IFX (condExpr))
3710 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3713 /* attach condition label to condition */
3714 condExpr = createLabel (condLabel, condExpr);
3716 /* attach body label to body */
3717 forBody = createLabel (trueLabel, forBody);
3719 /* attach continue to forLoop expression & attach */
3720 /* goto the forcond @ and of loopExpression */
3721 loopExpr = createLabel (continueLabel,
3725 newAst_VALUE (symbolVal (condLabel)),
3727 /* now start putting them together */
3728 forTree = newNode (NULLOP, initExpr, condExpr);
3729 forTree = newNode (NULLOP, forTree, forBody);
3730 forTree = newNode (NULLOP, forTree, loopExpr);
3731 /* finally add the break label */
3732 forTree = newNode (NULLOP, forTree,
3733 createLabel (falseLabel, NULL));
3737 /*-----------------------------------------------------------------*/
3738 /* createWhile - creates parse tree for while statement */
3739 /* the while statement will be created as follows */
3741 /* _while_continue_n: */
3742 /* condition_expression +-> trueLabel -> _while_boby_n */
3744 /* +-> falseLabel -> _while_break_n */
3745 /* _while_body_n: */
3747 /* goto _while_continue_n */
3748 /* _while_break_n: */
3749 /*-----------------------------------------------------------------*/
3751 createWhile (symbol * trueLabel, symbol * continueLabel,
3752 symbol * falseLabel, ast * condExpr, ast * whileBody)
3756 /* put the continue label */
3757 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3758 condExpr = createLabel (continueLabel, condExpr);
3759 condExpr->lineno = 0;
3761 /* put the body label in front of the body */
3762 whileBody = createLabel (trueLabel, whileBody);
3763 whileBody->lineno = 0;
3764 /* put a jump to continue at the end of the body */
3765 /* and put break label at the end of the body */
3766 whileBody = newNode (NULLOP,
3769 newAst_VALUE (symbolVal (continueLabel)),
3770 createLabel (falseLabel, NULL)));
3772 /* put it all together */
3773 if (IS_IFX (condExpr))
3774 whileTree = condExpr;
3777 whileTree = newNode (IFX, condExpr, NULL);
3778 /* put the true & false labels in place */
3779 whileTree->trueLabel = trueLabel;
3780 whileTree->falseLabel = falseLabel;
3783 return newNode (NULLOP, whileTree, whileBody);
3786 /*-----------------------------------------------------------------*/
3787 /* optimizeGetHbit - get highest order bit of the expression */
3788 /*-----------------------------------------------------------------*/
3790 optimizeGetHbit (ast * tree)
3793 /* if this is not a bit and */
3794 if (!IS_BITAND (tree))
3797 /* will look for tree of the form
3798 ( expr >> ((sizeof expr) -1) ) & 1 */
3799 if (!IS_AST_LIT_VALUE (tree->right))
3802 if (AST_LIT_VALUE (tree->right) != 1)
3805 if (!IS_RIGHT_OP (tree->left))
3808 if (!IS_AST_LIT_VALUE (tree->left->right))
3811 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3812 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3815 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3819 /*-----------------------------------------------------------------*/
3820 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3821 /*-----------------------------------------------------------------*/
3823 optimizeRRCRLC (ast * root)
3825 /* will look for trees of the form
3826 (?expr << 1) | (?expr >> 7) or
3827 (?expr >> 7) | (?expr << 1) will make that
3828 into a RLC : operation ..
3830 (?expr >> 1) | (?expr << 7) or
3831 (?expr << 7) | (?expr >> 1) will make that
3832 into a RRC operation
3833 note : by 7 I mean (number of bits required to hold the
3835 /* if the root operations is not a | operation the not */
3836 if (!IS_BITOR (root))
3839 /* I have to think of a better way to match patterns this sucks */
3840 /* that aside let start looking for the first case : I use a the
3841 negative check a lot to improve the efficiency */
3842 /* (?expr << 1) | (?expr >> 7) */
3843 if (IS_LEFT_OP (root->left) &&
3844 IS_RIGHT_OP (root->right))
3847 if (!SPEC_USIGN (TETYPE (root->left->left)))
3850 if (!IS_AST_LIT_VALUE (root->left->right) ||
3851 !IS_AST_LIT_VALUE (root->right->right))
3854 /* make sure it is the same expression */
3855 if (!isAstEqual (root->left->left,
3859 if (AST_LIT_VALUE (root->left->right) != 1)
3862 if (AST_LIT_VALUE (root->right->right) !=
3863 (getSize (TTYPE (root->left->left)) * 8 - 1))
3866 /* whew got the first case : create the AST */
3867 return newNode (RLC, root->left->left, NULL);
3871 /* check for second case */
3872 /* (?expr >> 7) | (?expr << 1) */
3873 if (IS_LEFT_OP (root->right) &&
3874 IS_RIGHT_OP (root->left))
3877 if (!SPEC_USIGN (TETYPE (root->left->left)))
3880 if (!IS_AST_LIT_VALUE (root->left->right) ||
3881 !IS_AST_LIT_VALUE (root->right->right))
3884 /* make sure it is the same symbol */
3885 if (!isAstEqual (root->left->left,
3889 if (AST_LIT_VALUE (root->right->right) != 1)
3892 if (AST_LIT_VALUE (root->left->right) !=
3893 (getSize (TTYPE (root->left->left)) * 8 - 1))
3896 /* whew got the first case : create the AST */
3897 return newNode (RLC, root->left->left, NULL);
3902 /* third case for RRC */
3903 /* (?symbol >> 1) | (?symbol << 7) */
3904 if (IS_LEFT_OP (root->right) &&
3905 IS_RIGHT_OP (root->left))
3908 if (!SPEC_USIGN (TETYPE (root->left->left)))
3911 if (!IS_AST_LIT_VALUE (root->left->right) ||
3912 !IS_AST_LIT_VALUE (root->right->right))
3915 /* make sure it is the same symbol */
3916 if (!isAstEqual (root->left->left,
3920 if (AST_LIT_VALUE (root->left->right) != 1)
3923 if (AST_LIT_VALUE (root->right->right) !=
3924 (getSize (TTYPE (root->left->left)) * 8 - 1))
3927 /* whew got the first case : create the AST */
3928 return newNode (RRC, root->left->left, NULL);
3932 /* fourth and last case for now */
3933 /* (?symbol << 7) | (?symbol >> 1) */
3934 if (IS_RIGHT_OP (root->right) &&
3935 IS_LEFT_OP (root->left))
3938 if (!SPEC_USIGN (TETYPE (root->left->left)))
3941 if (!IS_AST_LIT_VALUE (root->left->right) ||
3942 !IS_AST_LIT_VALUE (root->right->right))
3945 /* make sure it is the same symbol */
3946 if (!isAstEqual (root->left->left,
3950 if (AST_LIT_VALUE (root->right->right) != 1)
3953 if (AST_LIT_VALUE (root->left->right) !=
3954 (getSize (TTYPE (root->left->left)) * 8 - 1))
3957 /* whew got the first case : create the AST */
3958 return newNode (RRC, root->left->left, NULL);
3962 /* not found return root */
3966 /*-----------------------------------------------------------------*/
3967 /* optimizeCompare - otimizes compares for bit variables */
3968 /*-----------------------------------------------------------------*/
3970 optimizeCompare (ast * root)
3972 ast *optExpr = NULL;
3975 unsigned int litValue;
3977 /* if nothing then return nothing */
3981 /* if not a compare op then do leaves */
3982 if (!IS_COMPARE_OP (root))
3984 root->left = optimizeCompare (root->left);
3985 root->right = optimizeCompare (root->right);
3989 /* if left & right are the same then depending
3990 of the operation do */
3991 if (isAstEqual (root->left, root->right))
3993 switch (root->opval.op)
3998 optExpr = newAst_VALUE (constVal ("0"));
4003 optExpr = newAst_VALUE (constVal ("1"));
4007 return decorateType (optExpr);
4010 vleft = (root->left->type == EX_VALUE ?
4011 root->left->opval.val : NULL);
4013 vright = (root->right->type == EX_VALUE ?
4014 root->right->opval.val : NULL);
4016 /* if left is a BITVAR in BITSPACE */
4017 /* and right is a LITERAL then opt- */
4018 /* imize else do nothing */
4019 if (vleft && vright &&
4020 IS_BITVAR (vleft->etype) &&
4021 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4022 IS_LITERAL (vright->etype))
4025 /* if right side > 1 then comparison may never succeed */
4026 if ((litValue = (int) floatFromVal (vright)) > 1)
4028 werror (W_BAD_COMPARE);
4034 switch (root->opval.op)
4036 case '>': /* bit value greater than 1 cannot be */
4037 werror (W_BAD_COMPARE);
4041 case '<': /* bit value < 1 means 0 */
4043 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4046 case LE_OP: /* bit value <= 1 means no check */
4047 optExpr = newAst_VALUE (vright);
4050 case GE_OP: /* bit value >= 1 means only check for = */
4052 optExpr = newAst_VALUE (vleft);
4057 { /* literal is zero */
4058 switch (root->opval.op)
4060 case '<': /* bit value < 0 cannot be */
4061 werror (W_BAD_COMPARE);
4065 case '>': /* bit value > 0 means 1 */
4067 optExpr = newAst_VALUE (vleft);
4070 case LE_OP: /* bit value <= 0 means no check */
4071 case GE_OP: /* bit value >= 0 means no check */
4072 werror (W_BAD_COMPARE);
4076 case EQ_OP: /* bit == 0 means ! of bit */
4077 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4081 return decorateType (resolveSymbols (optExpr));
4082 } /* end-of-if of BITVAR */
4087 /*-----------------------------------------------------------------*/
4088 /* addSymToBlock : adds the symbol to the first block we find */
4089 /*-----------------------------------------------------------------*/
4091 addSymToBlock (symbol * sym, ast * tree)
4093 /* reached end of tree or a leaf */
4094 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4098 if (IS_AST_OP (tree) &&
4099 tree->opval.op == BLOCK)
4102 symbol *lsym = copySymbol (sym);
4104 lsym->next = AST_VALUES (tree, sym);
4105 AST_VALUES (tree, sym) = lsym;
4109 addSymToBlock (sym, tree->left);
4110 addSymToBlock (sym, tree->right);
4113 /*-----------------------------------------------------------------*/
4114 /* processRegParms - do processing for register parameters */
4115 /*-----------------------------------------------------------------*/
4117 processRegParms (value * args, ast * body)
4121 if (IS_REGPARM (args->etype))
4122 addSymToBlock (args->sym, body);
4127 /*-----------------------------------------------------------------*/
4128 /* resetParmKey - resets the operandkeys for the symbols */
4129 /*-----------------------------------------------------------------*/
4130 DEFSETFUNC (resetParmKey)
4141 /*-----------------------------------------------------------------*/
4142 /* createFunction - This is the key node that calls the iCode for */
4143 /* generating the code for a function. Note code */
4144 /* is generated function by function, later when */
4145 /* add inter-procedural analysis this will change */
4146 /*-----------------------------------------------------------------*/
4148 createFunction (symbol * name, ast * body)
4154 iCode *piCode = NULL;
4156 /* if check function return 0 then some problem */
4157 if (checkFunction (name) == 0)
4160 /* create a dummy block if none exists */
4162 body = newNode (BLOCK, NULL, NULL);
4166 /* check if the function name already in the symbol table */
4167 if ((csym = findSym (SymbolTab, NULL, name->name)))
4170 /* special case for compiler defined functions
4171 we need to add the name to the publics list : this
4172 actually means we are now compiling the compiler
4176 addSet (&publics, name);
4182 allocVariables (name);
4184 name->lastLine = yylineno;
4186 processFuncArgs (currFunc, 0);
4188 /* set the stack pointer */
4189 /* PENDING: check this for the mcs51 */
4190 stackPtr = -port->stack.direction * port->stack.call_overhead;
4191 if (IS_ISR (name->etype))
4192 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4193 if (IS_RENT (name->etype) || options.stackAuto)
4194 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4196 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4198 fetype = getSpec (name->type); /* get the specifier for the function */
4199 /* if this is a reentrant function then */
4200 if (IS_RENT (fetype))
4203 allocParms (name->args); /* allocate the parameters */
4205 /* do processing for parameters that are passed in registers */
4206 processRegParms (name->args, body);
4208 /* set the stack pointer */
4212 /* allocate & autoinit the block variables */
4213 processBlockVars (body, &stack, ALLOCATE);
4215 /* save the stack information */
4216 if (options.useXstack)
4217 name->xstack = SPEC_STAK (fetype) = stack;
4219 name->stack = SPEC_STAK (fetype) = stack;
4221 /* name needs to be mangled */
4222 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4224 body = resolveSymbols (body); /* resolve the symbols */
4225 body = decorateType (body); /* propagateType & do semantic checks */
4227 ex = newAst_VALUE (symbolVal (name)); /* create name */
4228 ex = newNode (FUNCTION, ex, body);
4229 ex->values.args = name->args;
4233 werror (E_FUNC_NO_CODE, name->name);
4237 /* create the node & generate intermediate code */
4239 codeOutFile = code->oFile;
4240 piCode = iCodeFromAst (ex);
4244 werror (E_FUNC_NO_CODE, name->name);
4248 eBBlockFromiCode (piCode);
4250 /* if there are any statics then do them */
4253 GcurMemmap = statsg;
4254 codeOutFile = statsg->oFile;
4255 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4261 /* dealloc the block variables */
4262 processBlockVars (body, &stack, DEALLOCATE);
4263 /* deallocate paramaters */
4264 deallocParms (name->args);
4266 if (IS_RENT (fetype))
4269 /* we are done freeup memory & cleanup */
4274 addSet (&operKeyReset, name);
4275 applyToSet (operKeyReset, resetParmKey);
4278 cdbStructBlock (1, cdbFile);
4280 cleanUpLevel (LabelTab, 0);
4281 cleanUpBlock (StructTab, 1);
4282 cleanUpBlock (TypedefTab, 1);
4284 xstack->syms = NULL;
4285 istack->syms = NULL;
4290 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4291 /*-----------------------------------------------------------------*/
4292 /* ast_print : prints the ast (for debugging purposes) */
4293 /*-----------------------------------------------------------------*/
4295 void ast_print (ast * tree, FILE *outfile, int indent)
4300 /* can print only decorated trees */
4301 if (!tree->decorated) return;
4303 /* if any child is an error | this one is an error do nothing */
4304 if (tree->isError ||
4305 (tree->left && tree->left->isError) ||
4306 (tree->right && tree->right->isError)) {
4307 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4311 /* print the line */
4312 /* if not block & function */
4313 if (tree->type == EX_OP &&
4314 (tree->opval.op != FUNCTION &&
4315 tree->opval.op != BLOCK &&
4316 tree->opval.op != NULLOP)) {
4319 if (tree->opval.op == FUNCTION) {
4320 fprintf(outfile,"FUNCTION (%p) type (",tree);
4321 printTypeChain (tree->ftype,outfile);
4322 fprintf(outfile,")\n");
4323 ast_print(tree->left,outfile,indent+4);
4324 ast_print(tree->right,outfile,indent+4);
4327 if (tree->opval.op == BLOCK) {
4328 symbol *decls = tree->values.sym;
4329 fprintf(outfile,"{\n");
4331 INDENT(indent+4,outfile);
4332 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4333 printTypeChain(decls->type,outfile);
4334 fprintf(outfile,")\n");
4336 decls = decls->next;
4338 ast_print(tree->right,outfile,indent+4);
4339 fprintf(outfile,"}\n");
4342 if (tree->opval.op == NULLOP) {
4343 fprintf(outfile,"\n");
4344 ast_print(tree->left,outfile,indent);
4345 fprintf(outfile,"\n");
4346 ast_print(tree->right,outfile,indent);
4349 INDENT(indent,outfile);
4351 /*------------------------------------------------------------------*/
4352 /*----------------------------*/
4353 /* leaf has been reached */
4354 /*----------------------------*/
4355 /* if this is of type value */
4356 /* just get the type */
4357 if (tree->type == EX_VALUE) {
4359 if (IS_LITERAL (tree->opval.val->etype)) {
4360 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4361 (int) floatFromVal(tree->opval.val),
4362 (int) floatFromVal(tree->opval.val),
4363 floatFromVal(tree->opval.val));
4364 } else if (tree->opval.val->sym) {
4365 /* if the undefined flag is set then give error message */
4366 if (tree->opval.val->sym->undefined) {
4367 fprintf(outfile,"UNDEFINED SYMBOL ");
4369 fprintf(outfile,"SYMBOL ");
4371 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4374 fprintf(outfile," type (");
4375 printTypeChain(tree->ftype,outfile);
4376 fprintf(outfile,")\n");
4378 fprintf(outfile,"\n");
4383 /* if type link for the case of cast */
4384 if (tree->type == EX_LINK) {
4385 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4386 printTypeChain(tree->opval.lnk,outfile);
4387 fprintf(outfile,")\n");
4392 /* depending on type of operator do */
4394 switch (tree->opval.op) {
4395 /*------------------------------------------------------------------*/
4396 /*----------------------------*/
4398 /*----------------------------*/
4400 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4401 printTypeChain(tree->ftype,outfile);
4402 fprintf(outfile,")\n");
4403 ast_print(tree->left,outfile,indent+4);
4404 ast_print(tree->right,outfile,indent+4);
4407 /*------------------------------------------------------------------*/
4408 /*----------------------------*/
4410 /*----------------------------*/
4412 fprintf(outfile,"STRUCT_ACCESS (%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 /*----------------------------*/
4421 /* struct/union pointer */
4422 /*----------------------------*/
4424 fprintf(outfile,"PTR_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 /* ++/-- operation */
4434 /*----------------------------*/
4435 case INC_OP: /* incerement operator unary so left only */
4436 fprintf(outfile,"INC_OP (%p) type (",tree);
4437 printTypeChain(tree->ftype,outfile);
4438 fprintf(outfile,")\n");
4439 ast_print(tree->left,outfile,indent+4);
4443 fprintf(outfile,"DEC_OP (%p) type (",tree);
4444 printTypeChain(tree->ftype,outfile);
4445 fprintf(outfile,")\n");
4446 ast_print(tree->left,outfile,indent+4);
4449 /*------------------------------------------------------------------*/
4450 /*----------------------------*/
4452 /*----------------------------*/
4455 fprintf(outfile,"& (%p) type (",tree);
4456 printTypeChain(tree->ftype,outfile);
4457 fprintf(outfile,")\n");
4458 ast_print(tree->left,outfile,indent+4);
4459 ast_print(tree->right,outfile,indent+4);
4461 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4462 printTypeChain(tree->ftype,outfile);
4463 fprintf(outfile,")\n");
4464 ast_print(tree->left,outfile,indent+4);
4465 ast_print(tree->right,outfile,indent+4);
4468 /*----------------------------*/
4470 /*----------------------------*/
4472 fprintf(outfile,"OR (%p) type (",tree);
4473 printTypeChain(tree->ftype,outfile);
4474 fprintf(outfile,")\n");
4475 ast_print(tree->left,outfile,indent+4);
4476 ast_print(tree->right,outfile,indent+4);
4478 /*------------------------------------------------------------------*/
4479 /*----------------------------*/
4481 /*----------------------------*/
4483 fprintf(outfile,"XOR (%p) type (",tree);
4484 printTypeChain(tree->ftype,outfile);
4485 fprintf(outfile,")\n");
4486 ast_print(tree->left,outfile,indent+4);
4487 ast_print(tree->right,outfile,indent+4);
4490 /*------------------------------------------------------------------*/
4491 /*----------------------------*/
4493 /*----------------------------*/
4495 fprintf(outfile,"DIV (%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);
4501 /*------------------------------------------------------------------*/
4502 /*----------------------------*/
4504 /*----------------------------*/
4506 fprintf(outfile,"MOD (%p) type (",tree);
4507 printTypeChain(tree->ftype,outfile);
4508 fprintf(outfile,")\n");
4509 ast_print(tree->left,outfile,indent+4);
4510 ast_print(tree->right,outfile,indent+4);
4513 /*------------------------------------------------------------------*/
4514 /*----------------------------*/
4515 /* address dereference */
4516 /*----------------------------*/
4517 case '*': /* can be unary : if right is null then unary operation */
4519 fprintf(outfile,"DEREF (%p) type (",tree);
4520 printTypeChain(tree->ftype,outfile);
4521 fprintf(outfile,")\n");
4522 ast_print(tree->left,outfile,indent+4);
4525 /*------------------------------------------------------------------*/
4526 /*----------------------------*/
4527 /* multiplication */
4528 /*----------------------------*/
4529 fprintf(outfile,"MULT (%p) type (",tree);
4530 printTypeChain(tree->ftype,outfile);
4531 fprintf(outfile,")\n");
4532 ast_print(tree->left,outfile,indent+4);
4533 ast_print(tree->right,outfile,indent+4);
4537 /*------------------------------------------------------------------*/
4538 /*----------------------------*/
4539 /* unary '+' operator */
4540 /*----------------------------*/
4544 fprintf(outfile,"UPLUS (%p) type (",tree);
4545 printTypeChain(tree->ftype,outfile);
4546 fprintf(outfile,")\n");
4547 ast_print(tree->left,outfile,indent+4);
4549 /*------------------------------------------------------------------*/
4550 /*----------------------------*/
4552 /*----------------------------*/
4553 fprintf(outfile,"ADD (%p) type (",tree);
4554 printTypeChain(tree->ftype,outfile);
4555 fprintf(outfile,")\n");
4556 ast_print(tree->left,outfile,indent+4);
4557 ast_print(tree->right,outfile,indent+4);
4560 /*------------------------------------------------------------------*/
4561 /*----------------------------*/
4563 /*----------------------------*/
4564 case '-': /* can be unary */
4566 fprintf(outfile,"UMINUS (%p) type (",tree);
4567 printTypeChain(tree->ftype,outfile);
4568 fprintf(outfile,")\n");
4569 ast_print(tree->left,outfile,indent+4);
4571 /*------------------------------------------------------------------*/
4572 /*----------------------------*/
4574 /*----------------------------*/
4575 fprintf(outfile,"SUB (%p) type (",tree);
4576 printTypeChain(tree->ftype,outfile);
4577 fprintf(outfile,")\n");
4578 ast_print(tree->left,outfile,indent+4);
4579 ast_print(tree->right,outfile,indent+4);
4582 /*------------------------------------------------------------------*/
4583 /*----------------------------*/
4585 /*----------------------------*/
4587 fprintf(outfile,"COMPL (%p) type (",tree);
4588 printTypeChain(tree->ftype,outfile);
4589 fprintf(outfile,")\n");
4590 ast_print(tree->left,outfile,indent+4);
4592 /*------------------------------------------------------------------*/
4593 /*----------------------------*/
4595 /*----------------------------*/
4597 fprintf(outfile,"NOT (%p) type (",tree);
4598 printTypeChain(tree->ftype,outfile);
4599 fprintf(outfile,")\n");
4600 ast_print(tree->left,outfile,indent+4);
4602 /*------------------------------------------------------------------*/
4603 /*----------------------------*/
4605 /*----------------------------*/
4607 fprintf(outfile,"RRC (%p) type (",tree);
4608 printTypeChain(tree->ftype,outfile);
4609 fprintf(outfile,")\n");
4610 ast_print(tree->left,outfile,indent+4);
4614 fprintf(outfile,"RLC (%p) type (",tree);
4615 printTypeChain(tree->ftype,outfile);
4616 fprintf(outfile,")\n");
4617 ast_print(tree->left,outfile,indent+4);
4620 fprintf(outfile,"GETHBIT (%p) type (",tree);
4621 printTypeChain(tree->ftype,outfile);
4622 fprintf(outfile,")\n");
4623 ast_print(tree->left,outfile,indent+4);
4626 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4627 printTypeChain(tree->ftype,outfile);
4628 fprintf(outfile,")\n");
4629 ast_print(tree->left,outfile,indent+4);
4630 ast_print(tree->right,outfile,indent+4);
4633 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4634 printTypeChain(tree->ftype,outfile);
4635 fprintf(outfile,")\n");
4636 ast_print(tree->left,outfile,indent+4);
4637 ast_print(tree->right,outfile,indent+4);
4639 /*------------------------------------------------------------------*/
4640 /*----------------------------*/
4642 /*----------------------------*/
4643 case CAST: /* change the type */
4644 fprintf(outfile,"CAST (%p) type (",tree);
4645 printTypeChain(tree->ftype,outfile);
4646 fprintf(outfile,")\n");
4647 ast_print(tree->right,outfile,indent+4);
4651 fprintf(outfile,"ANDAND (%p) type (",tree);
4652 printTypeChain(tree->ftype,outfile);
4653 fprintf(outfile,")\n");
4654 ast_print(tree->left,outfile,indent+4);
4655 ast_print(tree->right,outfile,indent+4);
4658 fprintf(outfile,"OROR (%p) type (",tree);
4659 printTypeChain(tree->ftype,outfile);
4660 fprintf(outfile,")\n");
4661 ast_print(tree->left,outfile,indent+4);
4662 ast_print(tree->right,outfile,indent+4);
4665 /*------------------------------------------------------------------*/
4666 /*----------------------------*/
4667 /* comparison operators */
4668 /*----------------------------*/
4670 fprintf(outfile,"GT(>) (%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 fprintf(outfile,"LT(<) (%p) type (",tree);
4678 printTypeChain(tree->ftype,outfile);
4679 fprintf(outfile,")\n");
4680 ast_print(tree->left,outfile,indent+4);
4681 ast_print(tree->right,outfile,indent+4);
4684 fprintf(outfile,"LE(<=) (%p) type (",tree);
4685 printTypeChain(tree->ftype,outfile);
4686 fprintf(outfile,")\n");
4687 ast_print(tree->left,outfile,indent+4);
4688 ast_print(tree->right,outfile,indent+4);
4691 fprintf(outfile,"GE(>=) (%p) type (",tree);
4692 printTypeChain(tree->ftype,outfile);
4693 fprintf(outfile,")\n");
4694 ast_print(tree->left,outfile,indent+4);
4695 ast_print(tree->right,outfile,indent+4);
4698 fprintf(outfile,"EQ(==) (%p) type (",tree);
4699 printTypeChain(tree->ftype,outfile);
4700 fprintf(outfile,")\n");
4701 ast_print(tree->left,outfile,indent+4);
4702 ast_print(tree->right,outfile,indent+4);
4705 fprintf(outfile,"NE(!=) (%p) type (",tree);
4706 printTypeChain(tree->ftype,outfile);
4707 fprintf(outfile,")\n");
4708 ast_print(tree->left,outfile,indent+4);
4709 ast_print(tree->right,outfile,indent+4);
4710 /*------------------------------------------------------------------*/
4711 /*----------------------------*/
4713 /*----------------------------*/
4714 case SIZEOF: /* evaluate wihout code generation */
4715 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4718 /*------------------------------------------------------------------*/
4719 /*----------------------------*/
4720 /* conditional operator '?' */
4721 /*----------------------------*/
4723 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4724 printTypeChain(tree->ftype,outfile);
4725 fprintf(outfile,")\n");
4726 ast_print(tree->left,outfile,indent+4);
4727 ast_print(tree->right,outfile,indent+4);
4730 fprintf(outfile,"COLON(:) (%p) type (",tree);
4731 printTypeChain(tree->ftype,outfile);
4732 fprintf(outfile,")\n");
4733 ast_print(tree->left,outfile,indent+4);
4734 ast_print(tree->right,outfile,indent+4);
4737 /*------------------------------------------------------------------*/
4738 /*----------------------------*/
4739 /* assignment operators */
4740 /*----------------------------*/
4742 fprintf(outfile,"MULASS(*=) (%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 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4750 printTypeChain(tree->ftype,outfile);
4751 fprintf(outfile,")\n");
4752 ast_print(tree->left,outfile,indent+4);
4753 ast_print(tree->right,outfile,indent+4);
4756 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4757 printTypeChain(tree->ftype,outfile);
4758 fprintf(outfile,")\n");
4759 ast_print(tree->left,outfile,indent+4);
4760 ast_print(tree->right,outfile,indent+4);
4763 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+4);
4767 ast_print(tree->right,outfile,indent+4);
4770 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4771 printTypeChain(tree->ftype,outfile);
4772 fprintf(outfile,")\n");
4773 ast_print(tree->left,outfile,indent+4);
4774 ast_print(tree->right,outfile,indent+4);
4777 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4778 printTypeChain(tree->ftype,outfile);
4779 fprintf(outfile,")\n");
4780 ast_print(tree->left,outfile,indent+4);
4781 ast_print(tree->right,outfile,indent+4);
4784 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4785 printTypeChain(tree->ftype,outfile);
4786 fprintf(outfile,")\n");
4787 ast_print(tree->left,outfile,indent+4);
4788 ast_print(tree->right,outfile,indent+4);
4790 /*------------------------------------------------------------------*/
4791 /*----------------------------*/
4793 /*----------------------------*/
4795 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4796 printTypeChain(tree->ftype,outfile);
4797 fprintf(outfile,")\n");
4798 ast_print(tree->left,outfile,indent+4);
4799 ast_print(tree->right,outfile,indent+4);
4801 /*------------------------------------------------------------------*/
4802 /*----------------------------*/
4804 /*----------------------------*/
4806 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4807 printTypeChain(tree->ftype,outfile);
4808 fprintf(outfile,")\n");
4809 ast_print(tree->left,outfile,indent+4);
4810 ast_print(tree->right,outfile,indent+4);
4812 /*------------------------------------------------------------------*/
4813 /*----------------------------*/
4814 /* straight assignemnt */
4815 /*----------------------------*/
4817 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4818 printTypeChain(tree->ftype,outfile);
4819 fprintf(outfile,")\n");
4820 ast_print(tree->left,outfile,indent+4);
4821 ast_print(tree->right,outfile,indent+4);
4823 /*------------------------------------------------------------------*/
4824 /*----------------------------*/
4825 /* comma operator */
4826 /*----------------------------*/
4828 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4829 printTypeChain(tree->ftype,outfile);
4830 fprintf(outfile,")\n");
4831 ast_print(tree->left,outfile,indent+4);
4832 ast_print(tree->right,outfile,indent+4);
4834 /*------------------------------------------------------------------*/
4835 /*----------------------------*/
4837 /*----------------------------*/
4840 fprintf(outfile,"CALL (%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);
4847 fprintf(outfile,"PARM ");
4848 ast_print(tree->left,outfile,indent+4);
4849 if (tree->right && !IS_AST_PARAM(tree->right)) {
4850 fprintf(outfile,"PARM ");
4851 ast_print(tree->right,outfile,indent+4);
4854 /*------------------------------------------------------------------*/
4855 /*----------------------------*/
4856 /* return statement */
4857 /*----------------------------*/
4859 fprintf(outfile,"RETURN (%p) type (",tree);
4860 printTypeChain(tree->right->ftype,outfile);
4861 fprintf(outfile,")\n");
4862 ast_print(tree->right,outfile,indent+4);
4864 /*------------------------------------------------------------------*/
4865 /*----------------------------*/
4866 /* label statement */
4867 /*----------------------------*/
4869 fprintf(outfile,"LABEL (%p)",tree);
4870 ast_print(tree->left,outfile,indent+4);
4871 ast_print(tree->right,outfile,indent);
4873 /*------------------------------------------------------------------*/
4874 /*----------------------------*/
4875 /* switch statement */
4876 /*----------------------------*/
4880 fprintf(outfile,"SWITCH (%p) ",tree);
4881 ast_print(tree->left,outfile,0);
4882 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4883 INDENT(indent+4,outfile);
4884 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4885 (int) floatFromVal(val),
4886 tree->values.switchVals.swNum,
4887 (int) floatFromVal(val));
4889 ast_print(tree->right,outfile,indent);
4892 /*------------------------------------------------------------------*/
4893 /*----------------------------*/
4895 /*----------------------------*/
4897 ast_print(tree->left,outfile,indent);
4898 INDENT(indent,outfile);
4899 fprintf(outfile,"IF (%p) \n",tree);
4900 if (tree->trueLabel) {
4901 INDENT(indent,outfile);
4902 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4904 if (tree->falseLabel) {
4905 INDENT(indent,outfile);
4906 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4908 ast_print(tree->right,outfile,indent);
4910 /*------------------------------------------------------------------*/
4911 /*----------------------------*/
4913 /*----------------------------*/
4915 fprintf(outfile,"FOR (%p) \n",tree);
4916 if (AST_FOR( tree, initExpr)) {
4917 INDENT(indent+4,outfile);
4918 fprintf(outfile,"INIT EXPR ");
4919 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4921 if (AST_FOR( tree, condExpr)) {
4922 INDENT(indent+4,outfile);
4923 fprintf(outfile,"COND EXPR ");
4924 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4926 if (AST_FOR( tree, loopExpr)) {
4927 INDENT(indent+4,outfile);
4928 fprintf(outfile,"LOOP EXPR ");
4929 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4931 fprintf(outfile,"FOR LOOP BODY \n");
4932 ast_print(tree->left,outfile,indent+4);
4941 ast_print(t,stdout,1);