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 */
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");
757 /* if the parameter is castable then add the cast */
758 if (compareType (defParm->type, actParm->ftype) < 0)
760 ast *pTree = resolveSymbols (copyAst (actParm));
762 /* now change the current one to a cast */
763 actParm->type = EX_OP;
764 actParm->opval.op = CAST;
765 actParm->left = newAst_LINK (defParm->type);
766 actParm->right = pTree;
767 actParm->etype = defParm->etype;
768 actParm->ftype = defParm->type;
771 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
773 actParm->argSym = defParm->sym;
774 /* make a copy and change the regparm type to the defined parm */
775 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
776 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
780 /*-----------------------------------------------------------------*/
781 /* createIvalType - generates ival for basic types */
782 /*-----------------------------------------------------------------*/
784 createIvalType (ast * sym, sym_link * type, initList * ilist)
788 /* if initList is deep */
789 if (ilist->type == INIT_DEEP)
790 ilist = ilist->init.deep;
792 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
793 return decorateType (newNode ('=', sym, iExpr));
796 /*-----------------------------------------------------------------*/
797 /* createIvalStruct - generates initial value for structures */
798 /*-----------------------------------------------------------------*/
800 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
806 sflds = SPEC_STRUCT (type)->fields;
807 if (ilist->type != INIT_DEEP)
809 werror (E_INIT_STRUCT, "");
813 iloop = ilist->init.deep;
815 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
819 /* if we have come to end */
823 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
824 lAst = decorateType (resolveSymbols (lAst));
825 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
831 /*-----------------------------------------------------------------*/
832 /* createIvalArray - generates code for array initialization */
833 /*-----------------------------------------------------------------*/
835 createIvalArray (ast * sym, sym_link * type, initList * ilist)
839 int lcnt = 0, size = 0;
840 literalList *literalL;
842 /* take care of the special case */
843 /* array of characters can be init */
845 if (IS_CHAR (type->next))
846 if ((rast = createIvalCharPtr (sym,
848 decorateType (resolveSymbols (list2expr (ilist))))))
850 return decorateType (resolveSymbols (rast));
852 /* not the special case */
853 if (ilist->type != INIT_DEEP)
855 werror (E_INIT_STRUCT, "");
859 iloop = ilist->init.deep;
860 lcnt = DCL_ELEM (type);
862 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
866 aSym = decorateType (resolveSymbols(sym));
868 rast = newNode(ARRAYINIT, aSym, NULL);
869 rast->values.constlist = literalL;
871 // Make sure size is set to length of initializer list.
878 if (lcnt && size > lcnt)
880 // Array size was specified, and we have more initializers than needed.
881 char *name=sym->opval.val->sym->name;
882 int lineno=sym->opval.val->sym->lineDef;
884 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
893 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
894 aSym = decorateType (resolveSymbols (aSym));
895 rast = createIval (aSym, type->next, iloop, rast);
896 iloop = (iloop ? iloop->next : NULL);
902 /* no of elements given and we */
903 /* have generated for all of them */
906 // there has to be a better way
907 char *name=sym->opval.val->sym->name;
908 int lineno=sym->opval.val->sym->lineDef;
909 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
916 /* if we have not been given a size */
917 if (!DCL_ELEM (type))
919 DCL_ELEM (type) = size;
922 return decorateType (resolveSymbols (rast));
926 /*-----------------------------------------------------------------*/
927 /* createIvalCharPtr - generates initial values for char pointers */
928 /*-----------------------------------------------------------------*/
930 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
934 /* if this is a pointer & right is a literal array then */
935 /* just assignment will do */
936 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
937 SPEC_SCLS (iexpr->etype) == S_CODE)
938 && IS_ARRAY (iexpr->ftype)))
939 return newNode ('=', sym, iexpr);
941 /* left side is an array so we have to assign each */
943 if ((IS_LITERAL (iexpr->etype) ||
944 SPEC_SCLS (iexpr->etype) == S_CODE)
945 && IS_ARRAY (iexpr->ftype))
947 /* for each character generate an assignment */
948 /* to the array element */
949 char *s = SPEC_CVAL (iexpr->etype).v_char;
954 rast = newNode (NULLOP,
958 newAst_VALUE (valueFromLit ((float) i))),
959 newAst_VALUE (valueFromLit (*s))));
963 rast = newNode (NULLOP,
967 newAst_VALUE (valueFromLit ((float) i))),
968 newAst_VALUE (valueFromLit (*s))));
969 return decorateType (resolveSymbols (rast));
975 /*-----------------------------------------------------------------*/
976 /* createIvalPtr - generates initial value for pointers */
977 /*-----------------------------------------------------------------*/
979 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
985 if (ilist->type == INIT_DEEP)
986 ilist = ilist->init.deep;
988 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
990 /* if character pointer */
991 if (IS_CHAR (type->next))
992 if ((rast = createIvalCharPtr (sym, type, iexpr)))
995 return newNode ('=', sym, iexpr);
998 /*-----------------------------------------------------------------*/
999 /* createIval - generates code for initial value */
1000 /*-----------------------------------------------------------------*/
1002 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1009 /* if structure then */
1010 if (IS_STRUCT (type))
1011 rast = createIvalStruct (sym, type, ilist);
1013 /* if this is a pointer */
1015 rast = createIvalPtr (sym, type, ilist);
1017 /* if this is an array */
1018 if (IS_ARRAY (type))
1019 rast = createIvalArray (sym, type, ilist);
1021 /* if type is SPECIFIER */
1023 rast = createIvalType (sym, type, ilist);
1026 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1028 return decorateType (resolveSymbols (rast));
1031 /*-----------------------------------------------------------------*/
1032 /* initAggregates - initialises aggregate variables with initv */
1033 /*-----------------------------------------------------------------*/
1035 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1037 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1041 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1043 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1044 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1045 "with -mmcs51 and --model-large");
1049 if (SPEC_OCLS(sym->etype)==xdata &&
1050 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1053 newSym=copySymbol (sym);
1054 SPEC_OCLS(newSym->etype)=code;
1055 sprintf (newSym->name, "%s_init__", sym->name);
1056 sprintf (newSym->rname,"%s_init__", sym->rname);
1057 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1059 // emit it in the static segment
1060 addSet(&statsg->syms, newSym);
1062 // now memcpy() the entire array from cseg
1063 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1064 newAst_VALUE (symbolVal (sym)),
1065 newAst_VALUE (symbolVal (newSym)));
1066 return decorateType(resolveSymbols(ast));
1070 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1073 /*-----------------------------------------------------------------*/
1074 /* gatherAutoInit - creates assignment expressions for initial */
1076 /*-----------------------------------------------------------------*/
1078 gatherAutoInit (symbol * autoChain)
1085 for (sym = autoChain; sym; sym = sym->next)
1088 /* resolve the symbols in the ival */
1090 resolveIvalSym (sym->ival);
1092 /* if this is a static variable & has an */
1093 /* initial value the code needs to be lifted */
1094 /* here to the main portion since they can be */
1095 /* initialised only once at the start */
1096 if (IS_STATIC (sym->etype) && sym->ival &&
1097 SPEC_SCLS (sym->etype) != S_CODE)
1101 // this can only be a constant
1102 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1103 werror (E_CONST_EXPECTED);
1106 /* insert the symbol into the symbol table */
1107 /* with level = 0 & name = rname */
1108 newSym = copySymbol (sym);
1109 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1111 /* now lift the code to main */
1112 if (IS_AGGREGATE (sym->type))
1113 work = initAggregates (sym, sym->ival, NULL);
1115 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1116 list2expr (sym->ival));
1118 setAstLineno (work, sym->lineDef);
1122 staticAutos = newNode (NULLOP, staticAutos, work);
1129 /* if there is an initial value */
1130 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1132 if (IS_AGGREGATE (sym->type))
1133 work = initAggregates (sym, sym->ival, NULL);
1135 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1136 list2expr (sym->ival));
1138 setAstLineno (work, sym->lineDef);
1141 init = newNode (NULLOP, init, work);
1150 /*-----------------------------------------------------------------*/
1151 /* stringToSymbol - creates a symbol from a literal string */
1152 /*-----------------------------------------------------------------*/
1154 stringToSymbol (value * val)
1156 char name[SDCC_NAME_MAX + 1];
1157 static int charLbl = 0;
1160 sprintf (name, "_str_%d", charLbl++);
1161 sym = newSymbol (name, 0); /* make it @ level 0 */
1162 strcpy (sym->rname, name);
1164 /* copy the type from the value passed */
1165 sym->type = copyLinkChain (val->type);
1166 sym->etype = getSpec (sym->type);
1167 /* change to storage class & output class */
1168 SPEC_SCLS (sym->etype) = S_CODE;
1169 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1170 SPEC_STAT (sym->etype) = 1;
1171 /* make the level & block = 0 */
1172 sym->block = sym->level = 0;
1174 /* create an ival */
1175 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1180 allocVariables (sym);
1183 return symbolVal (sym);
1187 /*-----------------------------------------------------------------*/
1188 /* processBlockVars - will go thru the ast looking for block if */
1189 /* a block is found then will allocate the syms */
1190 /* will also gather the auto inits present */
1191 /*-----------------------------------------------------------------*/
1193 processBlockVars (ast * tree, int *stack, int action)
1198 /* if this is a block */
1199 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1203 if (action == ALLOCATE)
1205 *stack += allocVariables (tree->values.sym);
1206 autoInit = gatherAutoInit (tree->values.sym);
1208 /* if there are auto inits then do them */
1210 tree->left = newNode (NULLOP, autoInit, tree->left);
1212 else /* action is deallocate */
1213 deallocLocal (tree->values.sym);
1216 processBlockVars (tree->left, stack, action);
1217 processBlockVars (tree->right, stack, action);
1221 /*-----------------------------------------------------------------*/
1222 /* constExprValue - returns the value of a constant expression */
1223 /* or NULL if it is not a constant expression */
1224 /*-----------------------------------------------------------------*/
1226 constExprValue (ast * cexpr, int check)
1228 cexpr = decorateType (resolveSymbols (cexpr));
1230 /* if this is not a constant then */
1231 if (!IS_LITERAL (cexpr->ftype))
1233 /* then check if this is a literal array
1235 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1236 SPEC_CVAL (cexpr->etype).v_char &&
1237 IS_ARRAY (cexpr->ftype))
1239 value *val = valFromType (cexpr->ftype);
1240 SPEC_SCLS (val->etype) = S_LITERAL;
1241 val->sym = cexpr->opval.val->sym;
1242 val->sym->type = copyLinkChain (cexpr->ftype);
1243 val->sym->etype = getSpec (val->sym->type);
1244 strcpy (val->name, cexpr->opval.val->sym->rname);
1248 /* if we are casting a literal value then */
1249 if (IS_AST_OP (cexpr) &&
1250 cexpr->opval.op == CAST &&
1251 IS_LITERAL (cexpr->left->ftype))
1252 return valCastLiteral (cexpr->ftype,
1253 floatFromVal (cexpr->left->opval.val));
1255 if (IS_AST_VALUE (cexpr))
1256 return cexpr->opval.val;
1259 werror (E_CONST_EXPECTED, "found expression");
1264 /* return the value */
1265 return cexpr->opval.val;
1269 /*-----------------------------------------------------------------*/
1270 /* isLabelInAst - will return true if a given label is found */
1271 /*-----------------------------------------------------------------*/
1273 isLabelInAst (symbol * label, ast * tree)
1275 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1278 if (IS_AST_OP (tree) &&
1279 tree->opval.op == LABEL &&
1280 isSymbolEqual (AST_SYMBOL (tree->left), label))
1283 return isLabelInAst (label, tree->right) &&
1284 isLabelInAst (label, tree->left);
1288 /*-----------------------------------------------------------------*/
1289 /* isLoopCountable - return true if the loop count can be determi- */
1290 /* -ned at compile time . */
1291 /*-----------------------------------------------------------------*/
1293 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1294 symbol ** sym, ast ** init, ast ** end)
1297 /* the loop is considered countable if the following
1298 conditions are true :-
1300 a) initExpr :- <sym> = <const>
1301 b) condExpr :- <sym> < <const1>
1302 c) loopExpr :- <sym> ++
1305 /* first check the initExpr */
1306 if (IS_AST_OP (initExpr) &&
1307 initExpr->opval.op == '=' && /* is assignment */
1308 IS_AST_SYM_VALUE (initExpr->left))
1309 { /* left is a symbol */
1311 *sym = AST_SYMBOL (initExpr->left);
1312 *init = initExpr->right;
1317 /* for now the symbol has to be of
1319 if (!IS_INTEGRAL ((*sym)->type))
1322 /* now check condExpr */
1323 if (IS_AST_OP (condExpr))
1326 switch (condExpr->opval.op)
1329 if (IS_AST_SYM_VALUE (condExpr->left) &&
1330 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1331 IS_AST_LIT_VALUE (condExpr->right))
1333 *end = condExpr->right;
1339 if (IS_AST_OP (condExpr->left) &&
1340 condExpr->left->opval.op == '>' &&
1341 IS_AST_LIT_VALUE (condExpr->left->right) &&
1342 IS_AST_SYM_VALUE (condExpr->left->left) &&
1343 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1346 *end = newNode ('+', condExpr->left->right,
1347 newAst_VALUE (constVal ("1")));
1358 /* check loop expression is of the form <sym>++ */
1359 if (!IS_AST_OP (loopExpr))
1362 /* check if <sym> ++ */
1363 if (loopExpr->opval.op == INC_OP)
1369 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1370 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1377 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1378 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1386 if (loopExpr->opval.op == ADD_ASSIGN)
1389 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1390 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1391 IS_AST_LIT_VALUE (loopExpr->right) &&
1392 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1400 /*-----------------------------------------------------------------*/
1401 /* astHasVolatile - returns true if ast contains any volatile */
1402 /*-----------------------------------------------------------------*/
1404 astHasVolatile (ast * tree)
1409 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1412 if (IS_AST_OP (tree))
1413 return astHasVolatile (tree->left) ||
1414 astHasVolatile (tree->right);
1419 /*-----------------------------------------------------------------*/
1420 /* astHasPointer - return true if the ast contains any ptr variable */
1421 /*-----------------------------------------------------------------*/
1423 astHasPointer (ast * tree)
1428 if (IS_AST_LINK (tree))
1431 /* if we hit an array expression then check
1432 only the left side */
1433 if (IS_AST_OP (tree) && tree->opval.op == '[')
1434 return astHasPointer (tree->left);
1436 if (IS_AST_VALUE (tree))
1437 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1439 return astHasPointer (tree->left) ||
1440 astHasPointer (tree->right);
1444 /*-----------------------------------------------------------------*/
1445 /* astHasSymbol - return true if the ast has the given symbol */
1446 /*-----------------------------------------------------------------*/
1448 astHasSymbol (ast * tree, symbol * sym)
1450 if (!tree || IS_AST_LINK (tree))
1453 if (IS_AST_VALUE (tree))
1455 if (IS_AST_SYM_VALUE (tree))
1456 return isSymbolEqual (AST_SYMBOL (tree), sym);
1461 return astHasSymbol (tree->left, sym) ||
1462 astHasSymbol (tree->right, sym);
1465 /*-----------------------------------------------------------------*/
1466 /* astHasDeref - return true if the ast has an indirect access */
1467 /*-----------------------------------------------------------------*/
1469 astHasDeref (ast * tree)
1471 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1474 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1476 return astHasDeref (tree->left) || astHasDeref (tree->right);
1479 /*-----------------------------------------------------------------*/
1480 /* isConformingBody - the loop body has to conform to a set of rules */
1481 /* for the loop to be considered reversible read on for rules */
1482 /*-----------------------------------------------------------------*/
1484 isConformingBody (ast * pbody, symbol * sym, ast * body)
1487 /* we are going to do a pre-order traversal of the
1488 tree && check for the following conditions. (essentially
1489 a set of very shallow tests )
1490 a) the sym passed does not participate in
1491 any arithmetic operation
1492 b) There are no function calls
1493 c) all jumps are within the body
1494 d) address of loop control variable not taken
1495 e) if an assignment has a pointer on the
1496 left hand side make sure right does not have
1497 loop control variable */
1499 /* if we reach the end or a leaf then true */
1500 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1504 /* if anything else is "volatile" */
1505 if (IS_VOLATILE (TETYPE (pbody)))
1508 /* we will walk the body in a pre-order traversal for
1510 switch (pbody->opval.op)
1512 /*------------------------------------------------------------------*/
1514 return isConformingBody (pbody->right, sym, body);
1516 /*------------------------------------------------------------------*/
1521 /*------------------------------------------------------------------*/
1522 case INC_OP: /* incerement operator unary so left only */
1525 /* sure we are not sym is not modified */
1527 IS_AST_SYM_VALUE (pbody->left) &&
1528 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1532 IS_AST_SYM_VALUE (pbody->right) &&
1533 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1538 /*------------------------------------------------------------------*/
1540 case '*': /* can be unary : if right is null then unary operation */
1545 /* if right is NULL then unary operation */
1546 /*------------------------------------------------------------------*/
1547 /*----------------------------*/
1549 /*----------------------------*/
1552 if (IS_AST_SYM_VALUE (pbody->left) &&
1553 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1556 return isConformingBody (pbody->left, sym, body);
1560 if (astHasSymbol (pbody->left, sym) ||
1561 astHasSymbol (pbody->right, sym))
1566 /*------------------------------------------------------------------*/
1574 if (IS_AST_SYM_VALUE (pbody->left) &&
1575 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1578 if (IS_AST_SYM_VALUE (pbody->right) &&
1579 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1582 return isConformingBody (pbody->left, sym, body) &&
1583 isConformingBody (pbody->right, sym, body);
1590 if (IS_AST_SYM_VALUE (pbody->left) &&
1591 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1593 return isConformingBody (pbody->left, sym, body);
1595 /*------------------------------------------------------------------*/
1607 case SIZEOF: /* evaluate wihout code generation */
1609 return isConformingBody (pbody->left, sym, body) &&
1610 isConformingBody (pbody->right, sym, body);
1612 /*------------------------------------------------------------------*/
1615 /* if left has a pointer & right has loop
1616 control variable then we cannot */
1617 if (astHasPointer (pbody->left) &&
1618 astHasSymbol (pbody->right, sym))
1620 if (astHasVolatile (pbody->left))
1623 if (IS_AST_SYM_VALUE (pbody->left) &&
1624 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1627 if (astHasVolatile (pbody->left))
1630 if (astHasDeref(pbody->right)) return FALSE;
1632 return isConformingBody (pbody->left, sym, body) &&
1633 isConformingBody (pbody->right, sym, body);
1644 assert ("Parser should not have generated this\n");
1646 /*------------------------------------------------------------------*/
1647 /*----------------------------*/
1648 /* comma operator */
1649 /*----------------------------*/
1651 return isConformingBody (pbody->left, sym, body) &&
1652 isConformingBody (pbody->right, sym, body);
1654 /*------------------------------------------------------------------*/
1655 /*----------------------------*/
1657 /*----------------------------*/
1661 /*------------------------------------------------------------------*/
1662 /*----------------------------*/
1663 /* return statement */
1664 /*----------------------------*/
1669 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1674 if (astHasSymbol (pbody->left, sym))
1681 return isConformingBody (pbody->left, sym, body) &&
1682 isConformingBody (pbody->right, sym, body);
1688 /*-----------------------------------------------------------------*/
1689 /* isLoopReversible - takes a for loop as input && returns true */
1690 /* if the for loop is reversible. If yes will set the value of */
1691 /* the loop control var & init value & termination value */
1692 /*-----------------------------------------------------------------*/
1694 isLoopReversible (ast * loop, symbol ** loopCntrl,
1695 ast ** init, ast ** end)
1697 /* if option says don't do it then don't */
1698 if (optimize.noLoopReverse)
1700 /* there are several tests to determine this */
1702 /* for loop has to be of the form
1703 for ( <sym> = <const1> ;
1704 [<sym> < <const2>] ;
1705 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1707 if (!isLoopCountable (AST_FOR (loop, initExpr),
1708 AST_FOR (loop, condExpr),
1709 AST_FOR (loop, loopExpr),
1710 loopCntrl, init, end))
1713 /* now do some serious checking on the body of the loop
1716 return isConformingBody (loop->left, *loopCntrl, loop->left);
1720 /*-----------------------------------------------------------------*/
1721 /* replLoopSym - replace the loop sym by loop sym -1 */
1722 /*-----------------------------------------------------------------*/
1724 replLoopSym (ast * body, symbol * sym)
1727 if (!body || IS_AST_LINK (body))
1730 if (IS_AST_SYM_VALUE (body))
1733 if (isSymbolEqual (AST_SYMBOL (body), sym))
1737 body->opval.op = '-';
1738 body->left = newAst_VALUE (symbolVal (sym));
1739 body->right = newAst_VALUE (constVal ("1"));
1747 replLoopSym (body->left, sym);
1748 replLoopSym (body->right, sym);
1752 /*-----------------------------------------------------------------*/
1753 /* reverseLoop - do the actual loop reversal */
1754 /*-----------------------------------------------------------------*/
1756 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1760 /* create the following tree
1765 if (sym) goto for_continue ;
1768 /* put it together piece by piece */
1769 rloop = newNode (NULLOP,
1770 createIf (newAst_VALUE (symbolVal (sym)),
1772 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1775 newAst_VALUE (symbolVal (sym)),
1778 replLoopSym (loop->left, sym);
1780 rloop = newNode (NULLOP,
1782 newAst_VALUE (symbolVal (sym)),
1783 newNode ('-', end, init)),
1784 createLabel (AST_FOR (loop, continueLabel),
1788 newNode (SUB_ASSIGN,
1789 newAst_VALUE (symbolVal (sym)),
1790 newAst_VALUE (constVal ("1"))),
1793 return decorateType (rloop);
1797 //#define DEMAND_INTEGER_PROMOTION
1799 #ifdef DEMAND_INTEGER_PROMOTION
1801 /*-----------------------------------------------------------------*/
1802 /* walk a tree looking for the leaves. Add a typecast to the given */
1803 /* type to each value leaf node. */
1804 /*-----------------------------------------------------------------*/
1806 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1808 if (!node || IS_CALLOP(node))
1810 /* WTF? We should never get here. */
1814 if (!node->left && !node->right)
1816 /* We're at a leaf; if it's a value, apply the typecast */
1817 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1819 *parentPtr = decorateType (newNode (CAST,
1820 newAst_LINK (copyLinkChain (type)),
1828 pushTypeCastToLeaves (type, node->left, &(node->left));
1832 pushTypeCastToLeaves (type, node->right, &(node->right));
1839 /*-----------------------------------------------------------------*/
1840 /* Given an assignment operation in a tree, determine if the LHS */
1841 /* (the result) has a different (integer) type than the RHS. */
1842 /* If so, walk the RHS and add a typecast to the type of the LHS */
1843 /* to all leaf nodes. */
1844 /*-----------------------------------------------------------------*/
1846 propAsgType (ast * tree)
1848 #ifdef DEMAND_INTEGER_PROMOTION
1849 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1851 /* Nothing to do here... */
1855 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1857 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1864 /*-----------------------------------------------------------------*/
1865 /* decorateType - compute type for this tree also does type cheking */
1866 /* this is done bottom up, since type have to flow upwards */
1867 /* it also does constant folding, and paramater checking */
1868 /*-----------------------------------------------------------------*/
1870 decorateType (ast * tree)
1878 /* if already has type then do nothing */
1879 if (tree->decorated)
1882 tree->decorated = 1;
1884 /* print the line */
1885 /* if not block & function */
1886 if (tree->type == EX_OP &&
1887 (tree->opval.op != FUNCTION &&
1888 tree->opval.op != BLOCK &&
1889 tree->opval.op != NULLOP))
1891 filename = tree->filename;
1892 lineno = tree->lineno;
1895 /* if any child is an error | this one is an error do nothing */
1896 if (tree->isError ||
1897 (tree->left && tree->left->isError) ||
1898 (tree->right && tree->right->isError))
1901 /*------------------------------------------------------------------*/
1902 /*----------------------------*/
1903 /* leaf has been reached */
1904 /*----------------------------*/
1905 /* if this is of type value */
1906 /* just get the type */
1907 if (tree->type == EX_VALUE)
1910 if (IS_LITERAL (tree->opval.val->etype))
1913 /* if this is a character array then declare it */
1914 if (IS_ARRAY (tree->opval.val->type))
1915 tree->opval.val = stringToSymbol (tree->opval.val);
1917 /* otherwise just copy the type information */
1918 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1919 if (funcInChain (tree->opval.val->type))
1921 tree->hasVargs = tree->opval.val->sym->hasVargs;
1922 tree->args = copyValueChain (tree->opval.val->sym->args);
1927 if (tree->opval.val->sym)
1929 /* if the undefined flag is set then give error message */
1930 if (tree->opval.val->sym->undefined)
1932 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1934 TTYPE (tree) = TETYPE (tree) =
1935 tree->opval.val->type = tree->opval.val->sym->type =
1936 tree->opval.val->etype = tree->opval.val->sym->etype =
1937 copyLinkChain (INTTYPE);
1942 /* if impilicit i.e. struct/union member then no type */
1943 if (tree->opval.val->sym->implicit)
1944 TTYPE (tree) = TETYPE (tree) = NULL;
1949 /* else copy the type */
1950 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1952 /* and mark it as referenced */
1953 tree->opval.val->sym->isref = 1;
1954 /* if this is of type function or function pointer */
1955 if (funcInChain (tree->opval.val->type))
1957 tree->hasVargs = tree->opval.val->sym->hasVargs;
1958 tree->args = copyValueChain (tree->opval.val->sym->args);
1968 /* if type link for the case of cast */
1969 if (tree->type == EX_LINK)
1971 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1978 dtl = decorateType (tree->left);
1979 dtr = decorateType (tree->right);
1981 /* this is to take care of situations
1982 when the tree gets rewritten */
1983 if (dtl != tree->left)
1985 if (dtr != tree->right)
1989 /* depending on type of operator do */
1991 switch (tree->opval.op)
1993 /*------------------------------------------------------------------*/
1994 /*----------------------------*/
1996 /*----------------------------*/
1999 /* determine which is the array & which the index */
2000 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2003 ast *tempTree = tree->left;
2004 tree->left = tree->right;
2005 tree->right = tempTree;
2008 /* first check if this is a array or a pointer */
2009 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2011 werror (E_NEED_ARRAY_PTR, "[]");
2012 goto errorTreeReturn;
2015 /* check if the type of the idx */
2016 if (!IS_INTEGRAL (RTYPE (tree)))
2018 werror (E_IDX_NOT_INT);
2019 goto errorTreeReturn;
2022 /* if the left is an rvalue then error */
2025 werror (E_LVALUE_REQUIRED, "array access");
2026 goto errorTreeReturn;
2029 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2030 if (IS_PTR(LTYPE(tree))) {
2031 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2035 /*------------------------------------------------------------------*/
2036 /*----------------------------*/
2038 /*----------------------------*/
2040 /* if this is not a structure */
2041 if (!IS_STRUCT (LTYPE (tree)))
2043 werror (E_STRUCT_UNION, ".");
2044 goto errorTreeReturn;
2046 TTYPE (tree) = structElemType (LTYPE (tree),
2047 (tree->right->type == EX_VALUE ?
2048 tree->right->opval.val : NULL), &tree->args);
2049 TETYPE (tree) = getSpec (TTYPE (tree));
2052 /*------------------------------------------------------------------*/
2053 /*----------------------------*/
2054 /* struct/union pointer */
2055 /*----------------------------*/
2057 /* if not pointer to a structure */
2058 if (!IS_PTR (LTYPE (tree)))
2060 werror (E_PTR_REQD);
2061 goto errorTreeReturn;
2064 if (!IS_STRUCT (LTYPE (tree)->next))
2066 werror (E_STRUCT_UNION, "->");
2067 goto errorTreeReturn;
2070 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2071 (tree->right->type == EX_VALUE ?
2072 tree->right->opval.val : NULL), &tree->args);
2073 TETYPE (tree) = getSpec (TTYPE (tree));
2076 /*------------------------------------------------------------------*/
2077 /*----------------------------*/
2078 /* ++/-- operation */
2079 /*----------------------------*/
2080 case INC_OP: /* incerement operator unary so left only */
2083 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2084 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2085 if (!tree->initMode) {
2086 if ((IS_SPEC(TETYPE(tree)) && IS_CONSTANT (TETYPE (tree))) ||
2087 (IS_PTR(TTYPE(tree)) && DCL_PTR_CONST(TTYPE(tree)))) {
2088 werror (E_CODE_WRITE, "++/--");
2099 /*------------------------------------------------------------------*/
2100 /*----------------------------*/
2102 /*----------------------------*/
2103 case '&': /* can be unary */
2104 /* if right is NULL then unary operation */
2105 if (tree->right) /* not an unary operation */
2108 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2110 werror (E_BITWISE_OP);
2111 werror (W_CONTINUE, "left & right types are ");
2112 printTypeChain (LTYPE (tree), stderr);
2113 fprintf (stderr, ",");
2114 printTypeChain (RTYPE (tree), stderr);
2115 fprintf (stderr, "\n");
2116 goto errorTreeReturn;
2119 /* if they are both literal */
2120 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2122 tree->type = EX_VALUE;
2123 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2124 valFromType (RETYPE (tree)), '&');
2126 tree->right = tree->left = NULL;
2127 TETYPE (tree) = tree->opval.val->etype;
2128 TTYPE (tree) = tree->opval.val->type;
2132 /* see if this is a GETHBIT operation if yes
2135 ast *otree = optimizeGetHbit (tree);
2138 return decorateType (otree);
2142 // we can't do this because of "(int & 0xff) << 3"
2144 /* if right or left is literal then result of that type */
2145 if (IS_LITERAL (RTYPE (tree)))
2148 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2149 TETYPE (tree) = getSpec (TTYPE (tree));
2150 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2154 if (IS_LITERAL (LTYPE (tree)))
2156 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2157 TETYPE (tree) = getSpec (TTYPE (tree));
2158 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2164 computeType (LTYPE (tree), RTYPE (tree));
2165 TETYPE (tree) = getSpec (TTYPE (tree));
2170 computeType (LTYPE (tree), RTYPE (tree));
2171 TETYPE (tree) = getSpec (TTYPE (tree));
2173 LRVAL (tree) = RRVAL (tree) = 1;
2177 /*------------------------------------------------------------------*/
2178 /*----------------------------*/
2180 /*----------------------------*/
2182 p->class = DECLARATOR;
2183 /* if bit field then error */
2184 if (IS_BITVAR (tree->left->etype))
2186 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2187 goto errorTreeReturn;
2190 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2192 werror (E_ILLEGAL_ADDR, "address of register variable");
2193 goto errorTreeReturn;
2196 if (IS_FUNC (LTYPE (tree)))
2198 werror (E_ILLEGAL_ADDR, "address of function");
2199 goto errorTreeReturn;
2204 werror (E_LVALUE_REQUIRED, "address of");
2205 goto errorTreeReturn;
2207 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2209 DCL_TYPE (p) = CPOINTER;
2210 DCL_PTR_CONST (p) = port->mem.code_ro;
2212 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2213 DCL_TYPE (p) = FPOINTER;
2214 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2215 DCL_TYPE (p) = PPOINTER;
2216 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2217 DCL_TYPE (p) = IPOINTER;
2218 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2219 DCL_TYPE (p) = EEPPOINTER;
2221 DCL_TYPE (p) = POINTER;
2223 if (IS_AST_SYM_VALUE (tree->left))
2225 AST_SYMBOL (tree->left)->addrtaken = 1;
2226 AST_SYMBOL (tree->left)->allocreq = 1;
2229 p->next = LTYPE (tree);
2231 TETYPE (tree) = getSpec (TTYPE (tree));
2232 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2233 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2238 /*------------------------------------------------------------------*/
2239 /*----------------------------*/
2241 /*----------------------------*/
2243 /* if the rewrite succeeds then don't go any furthur */
2245 ast *wtree = optimizeRRCRLC (tree);
2247 return decorateType (wtree);
2249 /*------------------------------------------------------------------*/
2250 /*----------------------------*/
2252 /*----------------------------*/
2254 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2256 werror (E_BITWISE_OP);
2257 werror (W_CONTINUE, "left & right types are ");
2258 printTypeChain (LTYPE (tree), stderr);
2259 fprintf (stderr, ",");
2260 printTypeChain (RTYPE (tree), stderr);
2261 fprintf (stderr, "\n");
2262 goto errorTreeReturn;
2265 /* if they are both literal then */
2266 /* rewrite the tree */
2267 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2269 tree->type = EX_VALUE;
2270 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2271 valFromType (RETYPE (tree)),
2273 tree->right = tree->left = NULL;
2274 TETYPE (tree) = tree->opval.val->etype;
2275 TTYPE (tree) = tree->opval.val->type;
2278 LRVAL (tree) = RRVAL (tree) = 1;
2279 TETYPE (tree) = getSpec (TTYPE (tree) =
2280 computeType (LTYPE (tree),
2283 /*------------------------------------------------------------------*/
2284 /*----------------------------*/
2286 /*----------------------------*/
2288 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2290 werror (E_INVALID_OP, "divide");
2291 goto errorTreeReturn;
2293 /* if they are both literal then */
2294 /* rewrite the tree */
2295 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2297 tree->type = EX_VALUE;
2298 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2299 valFromType (RETYPE (tree)));
2300 tree->right = tree->left = NULL;
2301 TETYPE (tree) = getSpec (TTYPE (tree) =
2302 tree->opval.val->type);
2305 LRVAL (tree) = RRVAL (tree) = 1;
2306 TETYPE (tree) = getSpec (TTYPE (tree) =
2307 computeType (LTYPE (tree),
2311 /*------------------------------------------------------------------*/
2312 /*----------------------------*/
2314 /*----------------------------*/
2316 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2318 werror (E_BITWISE_OP);
2319 werror (W_CONTINUE, "left & right types are ");
2320 printTypeChain (LTYPE (tree), stderr);
2321 fprintf (stderr, ",");
2322 printTypeChain (RTYPE (tree), stderr);
2323 fprintf (stderr, "\n");
2324 goto errorTreeReturn;
2326 /* if they are both literal then */
2327 /* rewrite the tree */
2328 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2330 tree->type = EX_VALUE;
2331 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2332 valFromType (RETYPE (tree)));
2333 tree->right = tree->left = NULL;
2334 TETYPE (tree) = getSpec (TTYPE (tree) =
2335 tree->opval.val->type);
2338 LRVAL (tree) = RRVAL (tree) = 1;
2339 TETYPE (tree) = getSpec (TTYPE (tree) =
2340 computeType (LTYPE (tree),
2344 /*------------------------------------------------------------------*/
2345 /*----------------------------*/
2346 /* address dereference */
2347 /*----------------------------*/
2348 case '*': /* can be unary : if right is null then unary operation */
2351 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2353 werror (E_PTR_REQD);
2354 goto errorTreeReturn;
2359 werror (E_LVALUE_REQUIRED, "pointer deref");
2360 goto errorTreeReturn;
2362 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2363 LTYPE (tree)->next : NULL);
2364 TETYPE (tree) = getSpec (TTYPE (tree));
2365 tree->args = tree->left->args;
2366 tree->hasVargs = tree->left->hasVargs;
2367 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2371 /*------------------------------------------------------------------*/
2372 /*----------------------------*/
2373 /* multiplication */
2374 /*----------------------------*/
2375 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2377 werror (E_INVALID_OP, "multiplication");
2378 goto errorTreeReturn;
2381 /* if they are both literal then */
2382 /* rewrite the tree */
2383 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2385 tree->type = EX_VALUE;
2386 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2387 valFromType (RETYPE (tree)));
2388 tree->right = tree->left = NULL;
2389 TETYPE (tree) = getSpec (TTYPE (tree) =
2390 tree->opval.val->type);
2394 /* if left is a literal exchange left & right */
2395 if (IS_LITERAL (LTYPE (tree)))
2397 ast *tTree = tree->left;
2398 tree->left = tree->right;
2399 tree->right = tTree;
2402 LRVAL (tree) = RRVAL (tree) = 1;
2403 /* promote result to int if left & right are char
2404 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2405 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2406 TETYPE (tree) = getSpec (TTYPE (tree) =
2407 computeType (LTYPE (tree),
2409 SPEC_NOUN(TETYPE(tree)) = V_INT;
2411 TETYPE (tree) = getSpec (TTYPE (tree) =
2412 computeType (LTYPE (tree),
2417 /*------------------------------------------------------------------*/
2418 /*----------------------------*/
2419 /* unary '+' operator */
2420 /*----------------------------*/
2425 if (!IS_INTEGRAL (LTYPE (tree)))
2427 werror (E_UNARY_OP, '+');
2428 goto errorTreeReturn;
2431 /* if left is a literal then do it */
2432 if (IS_LITERAL (LTYPE (tree)))
2434 tree->type = EX_VALUE;
2435 tree->opval.val = valFromType (LETYPE (tree));
2437 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2441 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2445 /*------------------------------------------------------------------*/
2446 /*----------------------------*/
2448 /*----------------------------*/
2450 /* this is not a unary operation */
2451 /* if both pointers then problem */
2452 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2453 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2455 werror (E_PTR_PLUS_PTR);
2456 goto errorTreeReturn;
2459 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2460 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2462 werror (E_PLUS_INVALID, "+");
2463 goto errorTreeReturn;
2466 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2467 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2469 werror (E_PLUS_INVALID, "+");
2470 goto errorTreeReturn;
2472 /* if they are both literal then */
2473 /* rewrite the tree */
2474 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2476 tree->type = EX_VALUE;
2477 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2478 valFromType (RETYPE (tree)));
2479 tree->right = tree->left = NULL;
2480 TETYPE (tree) = getSpec (TTYPE (tree) =
2481 tree->opval.val->type);
2485 /* if the right is a pointer or left is a literal
2486 xchange left & right */
2487 if (IS_ARRAY (RTYPE (tree)) ||
2488 IS_PTR (RTYPE (tree)) ||
2489 IS_LITERAL (LTYPE (tree)))
2491 ast *tTree = tree->left;
2492 tree->left = tree->right;
2493 tree->right = tTree;
2496 LRVAL (tree) = RRVAL (tree) = 1;
2497 /* if the left is a pointer */
2498 if (IS_PTR (LTYPE (tree)))
2499 TETYPE (tree) = getSpec (TTYPE (tree) =
2502 TETYPE (tree) = getSpec (TTYPE (tree) =
2503 computeType (LTYPE (tree),
2507 /*------------------------------------------------------------------*/
2508 /*----------------------------*/
2510 /*----------------------------*/
2511 case '-': /* can be unary */
2512 /* if right is null then unary */
2516 if (!IS_ARITHMETIC (LTYPE (tree)))
2518 werror (E_UNARY_OP, tree->opval.op);
2519 goto errorTreeReturn;
2522 /* if left is a literal then do it */
2523 if (IS_LITERAL (LTYPE (tree)))
2525 tree->type = EX_VALUE;
2526 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2528 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2529 SPEC_USIGN(TETYPE(tree)) = 0;
2533 TTYPE (tree) = LTYPE (tree);
2537 /*------------------------------------------------------------------*/
2538 /*----------------------------*/
2540 /*----------------------------*/
2542 if (!(IS_PTR (LTYPE (tree)) ||
2543 IS_ARRAY (LTYPE (tree)) ||
2544 IS_ARITHMETIC (LTYPE (tree))))
2546 werror (E_PLUS_INVALID, "-");
2547 goto errorTreeReturn;
2550 if (!(IS_PTR (RTYPE (tree)) ||
2551 IS_ARRAY (RTYPE (tree)) ||
2552 IS_ARITHMETIC (RTYPE (tree))))
2554 werror (E_PLUS_INVALID, "-");
2555 goto errorTreeReturn;
2558 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2559 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2560 IS_INTEGRAL (RTYPE (tree))))
2562 werror (E_PLUS_INVALID, "-");
2563 goto errorTreeReturn;
2566 /* if they are both literal then */
2567 /* rewrite the tree */
2568 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2570 tree->type = EX_VALUE;
2571 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2572 valFromType (RETYPE (tree)));
2573 tree->right = tree->left = NULL;
2574 TETYPE (tree) = getSpec (TTYPE (tree) =
2575 tree->opval.val->type);
2579 /* if the left & right are equal then zero */
2580 if (isAstEqual (tree->left, tree->right))
2582 tree->type = EX_VALUE;
2583 tree->left = tree->right = NULL;
2584 tree->opval.val = constVal ("0");
2585 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2589 /* if both of them are pointers or arrays then */
2590 /* the result is going to be an integer */
2591 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2592 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2593 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2595 /* if only the left is a pointer */
2596 /* then result is a pointer */
2597 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2598 TETYPE (tree) = getSpec (TTYPE (tree) =
2601 TETYPE (tree) = getSpec (TTYPE (tree) =
2602 computeType (LTYPE (tree),
2604 LRVAL (tree) = RRVAL (tree) = 1;
2607 /*------------------------------------------------------------------*/
2608 /*----------------------------*/
2610 /*----------------------------*/
2612 /* can be only integral type */
2613 if (!IS_INTEGRAL (LTYPE (tree)))
2615 werror (E_UNARY_OP, tree->opval.op);
2616 goto errorTreeReturn;
2619 /* if left is a literal then do it */
2620 if (IS_LITERAL (LTYPE (tree)))
2622 tree->type = EX_VALUE;
2623 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2625 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2629 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2632 /*------------------------------------------------------------------*/
2633 /*----------------------------*/
2635 /*----------------------------*/
2637 /* can be pointer */
2638 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2639 !IS_PTR (LTYPE (tree)) &&
2640 !IS_ARRAY (LTYPE (tree)))
2642 werror (E_UNARY_OP, tree->opval.op);
2643 goto errorTreeReturn;
2646 /* if left is a literal then do it */
2647 if (IS_LITERAL (LTYPE (tree)))
2649 tree->type = EX_VALUE;
2650 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2652 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2656 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2659 /*------------------------------------------------------------------*/
2660 /*----------------------------*/
2662 /*----------------------------*/
2665 TTYPE (tree) = LTYPE (tree);
2666 TETYPE (tree) = LETYPE (tree);
2670 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2675 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2677 werror (E_SHIFT_OP_INVALID);
2678 werror (W_CONTINUE, "left & right types are ");
2679 printTypeChain (LTYPE (tree), stderr);
2680 fprintf (stderr, ",");
2681 printTypeChain (RTYPE (tree), stderr);
2682 fprintf (stderr, "\n");
2683 goto errorTreeReturn;
2686 /* if they are both literal then */
2687 /* rewrite the tree */
2688 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2690 tree->type = EX_VALUE;
2691 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2692 valFromType (RETYPE (tree)),
2693 (tree->opval.op == LEFT_OP ? 1 : 0));
2694 tree->right = tree->left = NULL;
2695 TETYPE (tree) = getSpec (TTYPE (tree) =
2696 tree->opval.val->type);
2699 /* if only the right side is a literal & we are
2700 shifting more than size of the left operand then zero */
2701 if (IS_LITERAL (RTYPE (tree)) &&
2702 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2703 (getSize (LTYPE (tree)) * 8))
2705 werror (W_SHIFT_CHANGED,
2706 (tree->opval.op == LEFT_OP ? "left" : "right"));
2707 tree->type = EX_VALUE;
2708 tree->left = tree->right = NULL;
2709 tree->opval.val = constVal ("0");
2710 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2713 LRVAL (tree) = RRVAL (tree) = 1;
2714 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2716 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2720 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2724 /*------------------------------------------------------------------*/
2725 /*----------------------------*/
2727 /*----------------------------*/
2728 case CAST: /* change the type */
2729 /* cannot cast to an aggregate type */
2730 if (IS_AGGREGATE (LTYPE (tree)))
2732 werror (E_CAST_ILLEGAL);
2733 goto errorTreeReturn;
2736 /* make sure the type is complete and sane */
2737 checkTypeSanity(LETYPE(tree), "(cast)");
2740 /* if the right is a literal replace the tree */
2741 if (IS_LITERAL (RETYPE (tree))) {
2742 if (!IS_PTR (LTYPE (tree))) {
2743 tree->type = EX_VALUE;
2745 valCastLiteral (LTYPE (tree),
2746 floatFromVal (valFromType (RETYPE (tree))));
2749 TTYPE (tree) = tree->opval.val->type;
2750 tree->values.literalFromCast = 1;
2751 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2752 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2753 sym_link *rest = LTYPE(tree)->next;
2754 werror(W_LITERAL_GENERIC);
2755 TTYPE(tree) = newLink();
2756 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2757 TTYPE(tree)->next = rest;
2758 tree->left->opval.lnk = TTYPE(tree);
2761 TTYPE (tree) = LTYPE (tree);
2765 TTYPE (tree) = LTYPE (tree);
2769 /* if the right is a literal replace the tree */
2770 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2771 tree->type = EX_VALUE;
2773 valCastLiteral (LTYPE (tree),
2774 floatFromVal (valFromType (RETYPE (tree))));
2777 TTYPE (tree) = tree->opval.val->type;
2778 tree->values.literalFromCast = 1;
2780 TTYPE (tree) = LTYPE (tree);
2785 TETYPE (tree) = getSpec (TTYPE (tree));
2789 /*------------------------------------------------------------------*/
2790 /*----------------------------*/
2791 /* logical &&, || */
2792 /*----------------------------*/
2795 /* each must me arithmetic type or be a pointer */
2796 if (!IS_PTR (LTYPE (tree)) &&
2797 !IS_ARRAY (LTYPE (tree)) &&
2798 !IS_INTEGRAL (LTYPE (tree)))
2800 werror (E_COMPARE_OP);
2801 goto errorTreeReturn;
2804 if (!IS_PTR (RTYPE (tree)) &&
2805 !IS_ARRAY (RTYPE (tree)) &&
2806 !IS_INTEGRAL (RTYPE (tree)))
2808 werror (E_COMPARE_OP);
2809 goto errorTreeReturn;
2811 /* if they are both literal then */
2812 /* rewrite the tree */
2813 if (IS_LITERAL (RTYPE (tree)) &&
2814 IS_LITERAL (LTYPE (tree)))
2816 tree->type = EX_VALUE;
2817 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2818 valFromType (RETYPE (tree)),
2820 tree->right = tree->left = NULL;
2821 TETYPE (tree) = getSpec (TTYPE (tree) =
2822 tree->opval.val->type);
2825 LRVAL (tree) = RRVAL (tree) = 1;
2826 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2829 /*------------------------------------------------------------------*/
2830 /*----------------------------*/
2831 /* comparison operators */
2832 /*----------------------------*/
2840 ast *lt = optimizeCompare (tree);
2846 /* if they are pointers they must be castable */
2847 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2849 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2851 werror (E_COMPARE_OP);
2852 fprintf (stderr, "comparing type ");
2853 printTypeChain (LTYPE (tree), stderr);
2854 fprintf (stderr, "to type ");
2855 printTypeChain (RTYPE (tree), stderr);
2856 fprintf (stderr, "\n");
2857 goto errorTreeReturn;
2860 /* else they should be promotable to one another */
2863 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2864 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2866 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2868 werror (E_COMPARE_OP);
2869 fprintf (stderr, "comparing type ");
2870 printTypeChain (LTYPE (tree), stderr);
2871 fprintf (stderr, "to type ");
2872 printTypeChain (RTYPE (tree), stderr);
2873 fprintf (stderr, "\n");
2874 goto errorTreeReturn;
2878 /* if they are both literal then */
2879 /* rewrite the tree */
2880 if (IS_LITERAL (RTYPE (tree)) &&
2881 IS_LITERAL (LTYPE (tree)))
2883 tree->type = EX_VALUE;
2884 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2885 valFromType (RETYPE (tree)),
2887 tree->right = tree->left = NULL;
2888 TETYPE (tree) = getSpec (TTYPE (tree) =
2889 tree->opval.val->type);
2892 LRVAL (tree) = RRVAL (tree) = 1;
2893 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2896 /*------------------------------------------------------------------*/
2897 /*----------------------------*/
2899 /*----------------------------*/
2900 case SIZEOF: /* evaluate wihout code generation */
2901 /* change the type to a integer */
2902 tree->type = EX_VALUE;
2903 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2904 tree->opval.val = constVal (buffer);
2905 tree->right = tree->left = NULL;
2906 TETYPE (tree) = getSpec (TTYPE (tree) =
2907 tree->opval.val->type);
2910 /*------------------------------------------------------------------*/
2911 /*----------------------------*/
2912 /* conditional operator '?' */
2913 /*----------------------------*/
2915 /* the type is value of the colon operator (on the right) */
2916 assert(IS_COLON_OP(tree->right));
2917 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2918 TETYPE (tree) = getSpec (TTYPE (tree));
2922 /* if they don't match we have a problem */
2923 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2925 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2926 goto errorTreeReturn;
2929 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2930 TETYPE (tree) = getSpec (TTYPE (tree));
2934 /*------------------------------------------------------------------*/
2935 /*----------------------------*/
2936 /* assignment operators */
2937 /*----------------------------*/
2940 /* for these it must be both must be integral */
2941 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2942 !IS_ARITHMETIC (RTYPE (tree)))
2944 werror (E_OPS_INTEGRAL);
2945 goto errorTreeReturn;
2948 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2950 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2951 werror (E_CODE_WRITE, " ");
2955 werror (E_LVALUE_REQUIRED, "*= or /=");
2956 goto errorTreeReturn;
2969 /* for these it must be both must be integral */
2970 if (!IS_INTEGRAL (LTYPE (tree)) ||
2971 !IS_INTEGRAL (RTYPE (tree)))
2973 werror (E_OPS_INTEGRAL);
2974 goto errorTreeReturn;
2977 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2979 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2980 werror (E_CODE_WRITE, " ");
2984 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2985 goto errorTreeReturn;
2993 /*------------------------------------------------------------------*/
2994 /*----------------------------*/
2996 /*----------------------------*/
2998 if (!(IS_PTR (LTYPE (tree)) ||
2999 IS_ARITHMETIC (LTYPE (tree))))
3001 werror (E_PLUS_INVALID, "-=");
3002 goto errorTreeReturn;
3005 if (!(IS_PTR (RTYPE (tree)) ||
3006 IS_ARITHMETIC (RTYPE (tree))))
3008 werror (E_PLUS_INVALID, "-=");
3009 goto errorTreeReturn;
3012 TETYPE (tree) = getSpec (TTYPE (tree) =
3013 computeType (LTYPE (tree),
3016 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3017 werror (E_CODE_WRITE, " ");
3021 werror (E_LVALUE_REQUIRED, "-=");
3022 goto errorTreeReturn;
3030 /*------------------------------------------------------------------*/
3031 /*----------------------------*/
3033 /*----------------------------*/
3035 /* this is not a unary operation */
3036 /* if both pointers then problem */
3037 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3039 werror (E_PTR_PLUS_PTR);
3040 goto errorTreeReturn;
3043 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3045 werror (E_PLUS_INVALID, "+=");
3046 goto errorTreeReturn;
3049 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3051 werror (E_PLUS_INVALID, "+=");
3052 goto errorTreeReturn;
3055 TETYPE (tree) = getSpec (TTYPE (tree) =
3056 computeType (LTYPE (tree),
3059 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3060 werror (E_CODE_WRITE, " ");
3064 werror (E_LVALUE_REQUIRED, "+=");
3065 goto errorTreeReturn;
3068 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3069 tree->opval.op = '=';
3075 /*------------------------------------------------------------------*/
3076 /*----------------------------*/
3077 /* straight assignemnt */
3078 /*----------------------------*/
3080 /* cannot be an aggregate */
3081 if (IS_AGGREGATE (LTYPE (tree)))
3083 werror (E_AGGR_ASSIGN);
3084 goto errorTreeReturn;
3087 /* they should either match or be castable */
3088 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3090 werror (E_TYPE_MISMATCH, "assignment", " ");
3091 fprintf (stderr, "type --> '");
3092 printTypeChain (RTYPE (tree), stderr);
3093 fprintf (stderr, "' ");
3094 fprintf (stderr, "assigned to type --> '");
3095 printTypeChain (LTYPE (tree), stderr);
3096 fprintf (stderr, "'\n");
3097 goto errorTreeReturn;
3100 /* if the left side of the tree is of type void
3101 then report error */
3102 if (IS_VOID (LTYPE (tree)))
3104 werror (E_CAST_ZERO);
3105 fprintf (stderr, "type --> '");
3106 printTypeChain (RTYPE (tree), stderr);
3107 fprintf (stderr, "' ");
3108 fprintf (stderr, "assigned to type --> '");
3109 printTypeChain (LTYPE (tree), stderr);
3110 fprintf (stderr, "'\n");
3113 TETYPE (tree) = getSpec (TTYPE (tree) =
3117 if (!tree->initMode ) {
3118 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))) ||
3119 (IS_PTR(LTYPE(tree)) && DCL_PTR_CONST(LTYPE(tree)))) {
3120 werror (E_CODE_WRITE, " ");
3125 werror (E_LVALUE_REQUIRED, "=");
3126 goto errorTreeReturn;
3133 /*------------------------------------------------------------------*/
3134 /*----------------------------*/
3135 /* comma operator */
3136 /*----------------------------*/
3138 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3141 /*------------------------------------------------------------------*/
3142 /*----------------------------*/
3144 /*----------------------------*/
3148 if (processParms (tree->left,
3150 tree->right, &parmNumber, TRUE))
3151 goto errorTreeReturn;
3153 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3155 tree->left->args = reverseVal (tree->left->args);
3156 reverseParms (tree->right);
3159 tree->args = tree->left->args;
3160 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3163 /*------------------------------------------------------------------*/
3164 /*----------------------------*/
3165 /* return statement */
3166 /*----------------------------*/
3171 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3173 werror (W_RETURN_MISMATCH);
3174 goto errorTreeReturn;
3177 if (IS_VOID (currFunc->type->next)
3179 !IS_VOID (RTYPE (tree)))
3181 werror (E_FUNC_VOID);
3182 goto errorTreeReturn;
3185 /* if there is going to be a casing required then add it */
3186 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3188 #if 0 && defined DEMAND_INTEGER_PROMOTION
3189 if (IS_INTEGRAL (currFunc->type->next))
3191 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3197 decorateType (newNode (CAST,
3198 newAst_LINK (copyLinkChain (currFunc->type->next)),
3208 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3210 werror (E_VOID_FUNC, currFunc->name);
3211 goto errorTreeReturn;
3214 TTYPE (tree) = TETYPE (tree) = NULL;
3217 /*------------------------------------------------------------------*/
3218 /*----------------------------*/
3219 /* switch statement */
3220 /*----------------------------*/
3222 /* the switch value must be an integer */
3223 if (!IS_INTEGRAL (LTYPE (tree)))
3225 werror (E_SWITCH_NON_INTEGER);
3226 goto errorTreeReturn;
3229 TTYPE (tree) = TETYPE (tree) = NULL;
3232 /*------------------------------------------------------------------*/
3233 /*----------------------------*/
3235 /*----------------------------*/
3237 tree->left = backPatchLabels (tree->left,
3240 TTYPE (tree) = TETYPE (tree) = NULL;
3243 /*------------------------------------------------------------------*/
3244 /*----------------------------*/
3246 /*----------------------------*/
3249 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3250 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3251 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3253 /* if the for loop is reversible then
3254 reverse it otherwise do what we normally
3260 if (isLoopReversible (tree, &sym, &init, &end))
3261 return reverseLoop (tree, sym, init, end);
3263 return decorateType (createFor (AST_FOR (tree, trueLabel),
3264 AST_FOR (tree, continueLabel),
3265 AST_FOR (tree, falseLabel),
3266 AST_FOR (tree, condLabel),
3267 AST_FOR (tree, initExpr),
3268 AST_FOR (tree, condExpr),
3269 AST_FOR (tree, loopExpr),
3273 TTYPE (tree) = TETYPE (tree) = NULL;
3277 /* some error found this tree will be killed */
3279 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3280 tree->opval.op = NULLOP;
3286 /*-----------------------------------------------------------------*/
3287 /* sizeofOp - processes size of operation */
3288 /*-----------------------------------------------------------------*/
3290 sizeofOp (sym_link * type)
3294 /* make sure the type is complete and sane */
3295 checkTypeSanity(type, "(sizeof)");
3297 /* get the size and convert it to character */
3298 sprintf (buff, "%d", getSize (type));
3300 /* now convert into value */
3301 return constVal (buff);
3305 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3306 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3307 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3308 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3309 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3310 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3311 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3313 /*-----------------------------------------------------------------*/
3314 /* backPatchLabels - change and or not operators to flow control */
3315 /*-----------------------------------------------------------------*/
3317 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3323 if (!(IS_ANDORNOT (tree)))
3326 /* if this an and */
3329 static int localLbl = 0;
3332 sprintf (buffer, "_and_%d", localLbl++);
3333 localLabel = newSymbol (buffer, NestLevel);
3335 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3337 /* if left is already a IFX then just change the if true label in that */
3338 if (!IS_IFX (tree->left))
3339 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3341 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3342 /* right is a IFX then just join */
3343 if (IS_IFX (tree->right))
3344 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3346 tree->right = createLabel (localLabel, tree->right);
3347 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3349 return newNode (NULLOP, tree->left, tree->right);
3352 /* if this is an or operation */
3355 static int localLbl = 0;
3358 sprintf (buffer, "_or_%d", localLbl++);
3359 localLabel = newSymbol (buffer, NestLevel);
3361 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3363 /* if left is already a IFX then just change the if true label in that */
3364 if (!IS_IFX (tree->left))
3365 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3367 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3368 /* right is a IFX then just join */
3369 if (IS_IFX (tree->right))
3370 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3372 tree->right = createLabel (localLabel, tree->right);
3373 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3375 return newNode (NULLOP, tree->left, tree->right);
3381 int wasnot = IS_NOT (tree->left);
3382 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3384 /* if the left is already a IFX */
3385 if (!IS_IFX (tree->left))
3386 tree->left = newNode (IFX, tree->left, NULL);
3390 tree->left->trueLabel = trueLabel;
3391 tree->left->falseLabel = falseLabel;
3395 tree->left->trueLabel = falseLabel;
3396 tree->left->falseLabel = trueLabel;
3403 tree->trueLabel = trueLabel;
3404 tree->falseLabel = falseLabel;
3411 /*-----------------------------------------------------------------*/
3412 /* createBlock - create expression tree for block */
3413 /*-----------------------------------------------------------------*/
3415 createBlock (symbol * decl, ast * body)
3419 /* if the block has nothing */
3423 ex = newNode (BLOCK, NULL, body);
3424 ex->values.sym = decl;
3426 ex->right = ex->right;
3432 /*-----------------------------------------------------------------*/
3433 /* createLabel - creates the expression tree for labels */
3434 /*-----------------------------------------------------------------*/
3436 createLabel (symbol * label, ast * stmnt)
3439 char name[SDCC_NAME_MAX + 1];
3442 /* must create fresh symbol if the symbol name */
3443 /* exists in the symbol table, since there can */
3444 /* be a variable with the same name as the labl */
3445 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3446 (csym->level == label->level))
3447 label = newSymbol (label->name, label->level);
3449 /* change the name before putting it in add _ */
3450 sprintf (name, "%s", label->name);
3452 /* put the label in the LabelSymbol table */
3453 /* but first check if a label of the same */
3455 if ((csym = findSym (LabelTab, NULL, name)))
3456 werror (E_DUPLICATE_LABEL, label->name);
3458 addSym (LabelTab, label, name, label->level, 0, 0);
3461 label->key = labelKey++;
3462 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3468 /*-----------------------------------------------------------------*/
3469 /* createCase - generates the parsetree for a case statement */
3470 /*-----------------------------------------------------------------*/
3472 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3474 char caseLbl[SDCC_NAME_MAX + 1];
3478 /* if the switch statement does not exist */
3479 /* then case is out of context */
3482 werror (E_CASE_CONTEXT);
3486 caseVal = decorateType (resolveSymbols (caseVal));
3487 /* if not a constant then error */
3488 if (!IS_LITERAL (caseVal->ftype))
3490 werror (E_CASE_CONSTANT);
3494 /* if not a integer than error */
3495 if (!IS_INTEGRAL (caseVal->ftype))
3497 werror (E_CASE_NON_INTEGER);
3501 /* find the end of the switch values chain */
3502 if (!(val = swStat->values.switchVals.swVals))
3503 swStat->values.switchVals.swVals = caseVal->opval.val;
3506 /* also order the cases according to value */
3508 int cVal = (int) floatFromVal (caseVal->opval.val);
3509 while (val && (int) floatFromVal (val) < cVal)
3515 /* if we reached the end then */
3518 pval->next = caseVal->opval.val;
3522 /* we found a value greater than */
3523 /* the current value we must add this */
3524 /* before the value */
3525 caseVal->opval.val->next = val;
3527 /* if this was the first in chain */
3528 if (swStat->values.switchVals.swVals == val)
3529 swStat->values.switchVals.swVals =
3532 pval->next = caseVal->opval.val;
3537 /* create the case label */
3538 sprintf (caseLbl, "_case_%d_%d",
3539 swStat->values.switchVals.swNum,
3540 (int) floatFromVal (caseVal->opval.val));
3542 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3547 /*-----------------------------------------------------------------*/
3548 /* createDefault - creates the parse tree for the default statement */
3549 /*-----------------------------------------------------------------*/
3551 createDefault (ast * swStat, ast * stmnt)
3553 char defLbl[SDCC_NAME_MAX + 1];
3555 /* if the switch statement does not exist */
3556 /* then case is out of context */
3559 werror (E_CASE_CONTEXT);
3563 /* turn on the default flag */
3564 swStat->values.switchVals.swDefault = 1;
3566 /* create the label */
3567 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3568 return createLabel (newSymbol (defLbl, 0), stmnt);
3571 /*-----------------------------------------------------------------*/
3572 /* createIf - creates the parsetree for the if statement */
3573 /*-----------------------------------------------------------------*/
3575 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3577 static int Lblnum = 0;
3579 symbol *ifTrue, *ifFalse, *ifEnd;
3581 /* if neither exists */
3582 if (!elseBody && !ifBody)
3585 /* create the labels */
3586 sprintf (buffer, "_iffalse_%d", Lblnum);
3587 ifFalse = newSymbol (buffer, NestLevel);
3588 /* if no else body then end == false */
3593 sprintf (buffer, "_ifend_%d", Lblnum);
3594 ifEnd = newSymbol (buffer, NestLevel);
3597 sprintf (buffer, "_iftrue_%d", Lblnum);
3598 ifTrue = newSymbol (buffer, NestLevel);
3602 /* attach the ifTrue label to the top of it body */
3603 ifBody = createLabel (ifTrue, ifBody);
3604 /* attach a goto end to the ifBody if else is present */
3607 ifBody = newNode (NULLOP, ifBody,
3609 newAst_VALUE (symbolVal (ifEnd)),
3611 /* put the elseLabel on the else body */
3612 elseBody = createLabel (ifFalse, elseBody);
3613 /* out the end at the end of the body */
3614 elseBody = newNode (NULLOP,
3616 createLabel (ifEnd, NULL));
3620 ifBody = newNode (NULLOP, ifBody,
3621 createLabel (ifFalse, NULL));
3623 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3624 if (IS_IFX (condAst))
3627 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3629 return newNode (NULLOP, ifTree,
3630 newNode (NULLOP, ifBody, elseBody));
3634 /*-----------------------------------------------------------------*/
3635 /* createDo - creates parse tree for do */
3638 /* _docontinue_n: */
3639 /* condition_expression +-> trueLabel -> _dobody_n */
3641 /* +-> falseLabel-> _dobreak_n */
3643 /*-----------------------------------------------------------------*/
3645 createDo (symbol * trueLabel, symbol * continueLabel,
3646 symbol * falseLabel, ast * condAst, ast * doBody)
3651 /* if the body does not exist then it is simple */
3654 condAst = backPatchLabels (condAst, continueLabel, NULL);
3655 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3656 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3657 doTree->trueLabel = continueLabel;
3658 doTree->falseLabel = NULL;
3662 /* otherwise we have a body */
3663 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3665 /* attach the body label to the top */
3666 doBody = createLabel (trueLabel, doBody);
3667 /* attach the continue label to end of body */
3668 doBody = newNode (NULLOP, doBody,
3669 createLabel (continueLabel, NULL));
3671 /* now put the break label at the end */
3672 if (IS_IFX (condAst))
3675 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3677 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3679 /* putting it together */
3680 return newNode (NULLOP, doBody, doTree);
3683 /*-----------------------------------------------------------------*/
3684 /* createFor - creates parse tree for 'for' statement */
3687 /* condExpr +-> trueLabel -> _forbody_n */
3689 /* +-> falseLabel-> _forbreak_n */
3692 /* _forcontinue_n: */
3694 /* goto _forcond_n ; */
3696 /*-----------------------------------------------------------------*/
3698 createFor (symbol * trueLabel, symbol * continueLabel,
3699 symbol * falseLabel, symbol * condLabel,
3700 ast * initExpr, ast * condExpr, ast * loopExpr,
3705 /* if loopexpression not present then we can generate it */
3706 /* the same way as a while */
3708 return newNode (NULLOP, initExpr,
3709 createWhile (trueLabel, continueLabel,
3710 falseLabel, condExpr, forBody));
3711 /* vanilla for statement */
3712 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3714 if (condExpr && !IS_IFX (condExpr))
3715 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3718 /* attach condition label to condition */
3719 condExpr = createLabel (condLabel, condExpr);
3721 /* attach body label to body */
3722 forBody = createLabel (trueLabel, forBody);
3724 /* attach continue to forLoop expression & attach */
3725 /* goto the forcond @ and of loopExpression */
3726 loopExpr = createLabel (continueLabel,
3730 newAst_VALUE (symbolVal (condLabel)),
3732 /* now start putting them together */
3733 forTree = newNode (NULLOP, initExpr, condExpr);
3734 forTree = newNode (NULLOP, forTree, forBody);
3735 forTree = newNode (NULLOP, forTree, loopExpr);
3736 /* finally add the break label */
3737 forTree = newNode (NULLOP, forTree,
3738 createLabel (falseLabel, NULL));
3742 /*-----------------------------------------------------------------*/
3743 /* createWhile - creates parse tree for while statement */
3744 /* the while statement will be created as follows */
3746 /* _while_continue_n: */
3747 /* condition_expression +-> trueLabel -> _while_boby_n */
3749 /* +-> falseLabel -> _while_break_n */
3750 /* _while_body_n: */
3752 /* goto _while_continue_n */
3753 /* _while_break_n: */
3754 /*-----------------------------------------------------------------*/
3756 createWhile (symbol * trueLabel, symbol * continueLabel,
3757 symbol * falseLabel, ast * condExpr, ast * whileBody)
3761 /* put the continue label */
3762 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3763 condExpr = createLabel (continueLabel, condExpr);
3764 condExpr->lineno = 0;
3766 /* put the body label in front of the body */
3767 whileBody = createLabel (trueLabel, whileBody);
3768 whileBody->lineno = 0;
3769 /* put a jump to continue at the end of the body */
3770 /* and put break label at the end of the body */
3771 whileBody = newNode (NULLOP,
3774 newAst_VALUE (symbolVal (continueLabel)),
3775 createLabel (falseLabel, NULL)));
3777 /* put it all together */
3778 if (IS_IFX (condExpr))
3779 whileTree = condExpr;
3782 whileTree = newNode (IFX, condExpr, NULL);
3783 /* put the true & false labels in place */
3784 whileTree->trueLabel = trueLabel;
3785 whileTree->falseLabel = falseLabel;
3788 return newNode (NULLOP, whileTree, whileBody);
3791 /*-----------------------------------------------------------------*/
3792 /* optimizeGetHbit - get highest order bit of the expression */
3793 /*-----------------------------------------------------------------*/
3795 optimizeGetHbit (ast * tree)
3798 /* if this is not a bit and */
3799 if (!IS_BITAND (tree))
3802 /* will look for tree of the form
3803 ( expr >> ((sizeof expr) -1) ) & 1 */
3804 if (!IS_AST_LIT_VALUE (tree->right))
3807 if (AST_LIT_VALUE (tree->right) != 1)
3810 if (!IS_RIGHT_OP (tree->left))
3813 if (!IS_AST_LIT_VALUE (tree->left->right))
3816 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3817 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3820 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3824 /*-----------------------------------------------------------------*/
3825 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3826 /*-----------------------------------------------------------------*/
3828 optimizeRRCRLC (ast * root)
3830 /* will look for trees of the form
3831 (?expr << 1) | (?expr >> 7) or
3832 (?expr >> 7) | (?expr << 1) will make that
3833 into a RLC : operation ..
3835 (?expr >> 1) | (?expr << 7) or
3836 (?expr << 7) | (?expr >> 1) will make that
3837 into a RRC operation
3838 note : by 7 I mean (number of bits required to hold the
3840 /* if the root operations is not a | operation the not */
3841 if (!IS_BITOR (root))
3844 /* I have to think of a better way to match patterns this sucks */
3845 /* that aside let start looking for the first case : I use a the
3846 negative check a lot to improve the efficiency */
3847 /* (?expr << 1) | (?expr >> 7) */
3848 if (IS_LEFT_OP (root->left) &&
3849 IS_RIGHT_OP (root->right))
3852 if (!SPEC_USIGN (TETYPE (root->left->left)))
3855 if (!IS_AST_LIT_VALUE (root->left->right) ||
3856 !IS_AST_LIT_VALUE (root->right->right))
3859 /* make sure it is the same expression */
3860 if (!isAstEqual (root->left->left,
3864 if (AST_LIT_VALUE (root->left->right) != 1)
3867 if (AST_LIT_VALUE (root->right->right) !=
3868 (getSize (TTYPE (root->left->left)) * 8 - 1))
3871 /* whew got the first case : create the AST */
3872 return newNode (RLC, root->left->left, NULL);
3876 /* check for second case */
3877 /* (?expr >> 7) | (?expr << 1) */
3878 if (IS_LEFT_OP (root->right) &&
3879 IS_RIGHT_OP (root->left))
3882 if (!SPEC_USIGN (TETYPE (root->left->left)))
3885 if (!IS_AST_LIT_VALUE (root->left->right) ||
3886 !IS_AST_LIT_VALUE (root->right->right))
3889 /* make sure it is the same symbol */
3890 if (!isAstEqual (root->left->left,
3894 if (AST_LIT_VALUE (root->right->right) != 1)
3897 if (AST_LIT_VALUE (root->left->right) !=
3898 (getSize (TTYPE (root->left->left)) * 8 - 1))
3901 /* whew got the first case : create the AST */
3902 return newNode (RLC, root->left->left, NULL);
3907 /* third case for RRC */
3908 /* (?symbol >> 1) | (?symbol << 7) */
3909 if (IS_LEFT_OP (root->right) &&
3910 IS_RIGHT_OP (root->left))
3913 if (!SPEC_USIGN (TETYPE (root->left->left)))
3916 if (!IS_AST_LIT_VALUE (root->left->right) ||
3917 !IS_AST_LIT_VALUE (root->right->right))
3920 /* make sure it is the same symbol */
3921 if (!isAstEqual (root->left->left,
3925 if (AST_LIT_VALUE (root->left->right) != 1)
3928 if (AST_LIT_VALUE (root->right->right) !=
3929 (getSize (TTYPE (root->left->left)) * 8 - 1))
3932 /* whew got the first case : create the AST */
3933 return newNode (RRC, root->left->left, NULL);
3937 /* fourth and last case for now */
3938 /* (?symbol << 7) | (?symbol >> 1) */
3939 if (IS_RIGHT_OP (root->right) &&
3940 IS_LEFT_OP (root->left))
3943 if (!SPEC_USIGN (TETYPE (root->left->left)))
3946 if (!IS_AST_LIT_VALUE (root->left->right) ||
3947 !IS_AST_LIT_VALUE (root->right->right))
3950 /* make sure it is the same symbol */
3951 if (!isAstEqual (root->left->left,
3955 if (AST_LIT_VALUE (root->right->right) != 1)
3958 if (AST_LIT_VALUE (root->left->right) !=
3959 (getSize (TTYPE (root->left->left)) * 8 - 1))
3962 /* whew got the first case : create the AST */
3963 return newNode (RRC, root->left->left, NULL);
3967 /* not found return root */
3971 /*-----------------------------------------------------------------*/
3972 /* optimizeCompare - otimizes compares for bit variables */
3973 /*-----------------------------------------------------------------*/
3975 optimizeCompare (ast * root)
3977 ast *optExpr = NULL;
3980 unsigned int litValue;
3982 /* if nothing then return nothing */
3986 /* if not a compare op then do leaves */
3987 if (!IS_COMPARE_OP (root))
3989 root->left = optimizeCompare (root->left);
3990 root->right = optimizeCompare (root->right);
3994 /* if left & right are the same then depending
3995 of the operation do */
3996 if (isAstEqual (root->left, root->right))
3998 switch (root->opval.op)
4003 optExpr = newAst_VALUE (constVal ("0"));
4008 optExpr = newAst_VALUE (constVal ("1"));
4012 return decorateType (optExpr);
4015 vleft = (root->left->type == EX_VALUE ?
4016 root->left->opval.val : NULL);
4018 vright = (root->right->type == EX_VALUE ?
4019 root->right->opval.val : NULL);
4021 /* if left is a BITVAR in BITSPACE */
4022 /* and right is a LITERAL then opt- */
4023 /* imize else do nothing */
4024 if (vleft && vright &&
4025 IS_BITVAR (vleft->etype) &&
4026 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4027 IS_LITERAL (vright->etype))
4030 /* if right side > 1 then comparison may never succeed */
4031 if ((litValue = (int) floatFromVal (vright)) > 1)
4033 werror (W_BAD_COMPARE);
4039 switch (root->opval.op)
4041 case '>': /* bit value greater than 1 cannot be */
4042 werror (W_BAD_COMPARE);
4046 case '<': /* bit value < 1 means 0 */
4048 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4051 case LE_OP: /* bit value <= 1 means no check */
4052 optExpr = newAst_VALUE (vright);
4055 case GE_OP: /* bit value >= 1 means only check for = */
4057 optExpr = newAst_VALUE (vleft);
4062 { /* literal is zero */
4063 switch (root->opval.op)
4065 case '<': /* bit value < 0 cannot be */
4066 werror (W_BAD_COMPARE);
4070 case '>': /* bit value > 0 means 1 */
4072 optExpr = newAst_VALUE (vleft);
4075 case LE_OP: /* bit value <= 0 means no check */
4076 case GE_OP: /* bit value >= 0 means no check */
4077 werror (W_BAD_COMPARE);
4081 case EQ_OP: /* bit == 0 means ! of bit */
4082 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4086 return decorateType (resolveSymbols (optExpr));
4087 } /* end-of-if of BITVAR */
4092 /*-----------------------------------------------------------------*/
4093 /* addSymToBlock : adds the symbol to the first block we find */
4094 /*-----------------------------------------------------------------*/
4096 addSymToBlock (symbol * sym, ast * tree)
4098 /* reached end of tree or a leaf */
4099 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4103 if (IS_AST_OP (tree) &&
4104 tree->opval.op == BLOCK)
4107 symbol *lsym = copySymbol (sym);
4109 lsym->next = AST_VALUES (tree, sym);
4110 AST_VALUES (tree, sym) = lsym;
4114 addSymToBlock (sym, tree->left);
4115 addSymToBlock (sym, tree->right);
4118 /*-----------------------------------------------------------------*/
4119 /* processRegParms - do processing for register parameters */
4120 /*-----------------------------------------------------------------*/
4122 processRegParms (value * args, ast * body)
4126 if (IS_REGPARM (args->etype))
4127 addSymToBlock (args->sym, body);
4132 /*-----------------------------------------------------------------*/
4133 /* resetParmKey - resets the operandkeys for the symbols */
4134 /*-----------------------------------------------------------------*/
4135 DEFSETFUNC (resetParmKey)
4146 /*-----------------------------------------------------------------*/
4147 /* createFunction - This is the key node that calls the iCode for */
4148 /* generating the code for a function. Note code */
4149 /* is generated function by function, later when */
4150 /* add inter-procedural analysis this will change */
4151 /*-----------------------------------------------------------------*/
4153 createFunction (symbol * name, ast * body)
4159 iCode *piCode = NULL;
4161 /* if check function return 0 then some problem */
4162 if (checkFunction (name) == 0)
4165 /* create a dummy block if none exists */
4167 body = newNode (BLOCK, NULL, NULL);
4171 /* check if the function name already in the symbol table */
4172 if ((csym = findSym (SymbolTab, NULL, name->name)))
4175 /* special case for compiler defined functions
4176 we need to add the name to the publics list : this
4177 actually means we are now compiling the compiler
4181 addSet (&publics, name);
4187 allocVariables (name);
4189 name->lastLine = yylineno;
4191 processFuncArgs (currFunc, 0);
4193 /* set the stack pointer */
4194 /* PENDING: check this for the mcs51 */
4195 stackPtr = -port->stack.direction * port->stack.call_overhead;
4196 if (IS_ISR (name->etype))
4197 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4198 if (IS_RENT (name->etype) || options.stackAuto)
4199 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4201 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4203 fetype = getSpec (name->type); /* get the specifier for the function */
4204 /* if this is a reentrant function then */
4205 if (IS_RENT (fetype))
4208 allocParms (name->args); /* allocate the parameters */
4210 /* do processing for parameters that are passed in registers */
4211 processRegParms (name->args, body);
4213 /* set the stack pointer */
4217 /* allocate & autoinit the block variables */
4218 processBlockVars (body, &stack, ALLOCATE);
4220 /* save the stack information */
4221 if (options.useXstack)
4222 name->xstack = SPEC_STAK (fetype) = stack;
4224 name->stack = SPEC_STAK (fetype) = stack;
4226 /* name needs to be mangled */
4227 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4229 body = resolveSymbols (body); /* resolve the symbols */
4230 body = decorateType (body); /* propagateType & do semantic checks */
4232 ex = newAst_VALUE (symbolVal (name)); /* create name */
4233 ex = newNode (FUNCTION, ex, body);
4234 ex->values.args = name->args;
4238 werror (E_FUNC_NO_CODE, name->name);
4242 /* create the node & generate intermediate code */
4244 codeOutFile = code->oFile;
4245 piCode = iCodeFromAst (ex);
4249 werror (E_FUNC_NO_CODE, name->name);
4253 eBBlockFromiCode (piCode);
4255 /* if there are any statics then do them */
4258 GcurMemmap = statsg;
4259 codeOutFile = statsg->oFile;
4260 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4266 /* dealloc the block variables */
4267 processBlockVars (body, &stack, DEALLOCATE);
4268 /* deallocate paramaters */
4269 deallocParms (name->args);
4271 if (IS_RENT (fetype))
4274 /* we are done freeup memory & cleanup */
4279 addSet (&operKeyReset, name);
4280 applyToSet (operKeyReset, resetParmKey);
4283 cdbStructBlock (1, cdbFile);
4285 cleanUpLevel (LabelTab, 0);
4286 cleanUpBlock (StructTab, 1);
4287 cleanUpBlock (TypedefTab, 1);
4289 xstack->syms = NULL;
4290 istack->syms = NULL;
4295 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4296 /*-----------------------------------------------------------------*/
4297 /* ast_print : prints the ast (for debugging purposes) */
4298 /*-----------------------------------------------------------------*/
4300 void ast_print (ast * tree, FILE *outfile, int indent)
4305 /* can print only decorated trees */
4306 if (!tree->decorated) return;
4308 /* if any child is an error | this one is an error do nothing */
4309 if (tree->isError ||
4310 (tree->left && tree->left->isError) ||
4311 (tree->right && tree->right->isError)) {
4312 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4316 /* print the line */
4317 /* if not block & function */
4318 if (tree->type == EX_OP &&
4319 (tree->opval.op != FUNCTION &&
4320 tree->opval.op != BLOCK &&
4321 tree->opval.op != NULLOP)) {
4324 if (tree->opval.op == FUNCTION) {
4325 fprintf(outfile,"FUNCTION (%p) type (",tree);
4326 printTypeChain (tree->ftype,outfile);
4327 fprintf(outfile,")\n");
4328 ast_print(tree->left,outfile,indent+4);
4329 ast_print(tree->right,outfile,indent+4);
4332 if (tree->opval.op == BLOCK) {
4333 symbol *decls = tree->values.sym;
4334 fprintf(outfile,"{\n");
4336 INDENT(indent+4,outfile);
4337 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4338 printTypeChain(decls->type,outfile);
4339 fprintf(outfile,")\n");
4341 decls = decls->next;
4343 ast_print(tree->right,outfile,indent+4);
4344 fprintf(outfile,"}\n");
4347 if (tree->opval.op == NULLOP) {
4348 fprintf(outfile,"\n");
4349 ast_print(tree->left,outfile,indent);
4350 fprintf(outfile,"\n");
4351 ast_print(tree->right,outfile,indent);
4354 INDENT(indent,outfile);
4356 /*------------------------------------------------------------------*/
4357 /*----------------------------*/
4358 /* leaf has been reached */
4359 /*----------------------------*/
4360 /* if this is of type value */
4361 /* just get the type */
4362 if (tree->type == EX_VALUE) {
4364 if (IS_LITERAL (tree->opval.val->etype)) {
4365 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4366 (int) floatFromVal(tree->opval.val),
4367 (int) floatFromVal(tree->opval.val),
4368 floatFromVal(tree->opval.val));
4369 } else if (tree->opval.val->sym) {
4370 /* if the undefined flag is set then give error message */
4371 if (tree->opval.val->sym->undefined) {
4372 fprintf(outfile,"UNDEFINED SYMBOL ");
4374 fprintf(outfile,"SYMBOL ");
4376 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4379 fprintf(outfile," type (");
4380 printTypeChain(tree->ftype,outfile);
4381 fprintf(outfile,")\n");
4383 fprintf(outfile,"\n");
4388 /* if type link for the case of cast */
4389 if (tree->type == EX_LINK) {
4390 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4391 printTypeChain(tree->opval.lnk,outfile);
4392 fprintf(outfile,")\n");
4397 /* depending on type of operator do */
4399 switch (tree->opval.op) {
4400 /*------------------------------------------------------------------*/
4401 /*----------------------------*/
4403 /*----------------------------*/
4405 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4406 printTypeChain(tree->ftype,outfile);
4407 fprintf(outfile,")\n");
4408 ast_print(tree->left,outfile,indent+4);
4409 ast_print(tree->right,outfile,indent+4);
4412 /*------------------------------------------------------------------*/
4413 /*----------------------------*/
4415 /*----------------------------*/
4417 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4418 printTypeChain(tree->ftype,outfile);
4419 fprintf(outfile,")\n");
4420 ast_print(tree->left,outfile,indent+4);
4421 ast_print(tree->right,outfile,indent+4);
4424 /*------------------------------------------------------------------*/
4425 /*----------------------------*/
4426 /* struct/union pointer */
4427 /*----------------------------*/
4429 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4430 printTypeChain(tree->ftype,outfile);
4431 fprintf(outfile,")\n");
4432 ast_print(tree->left,outfile,indent+4);
4433 ast_print(tree->right,outfile,indent+4);
4436 /*------------------------------------------------------------------*/
4437 /*----------------------------*/
4438 /* ++/-- operation */
4439 /*----------------------------*/
4440 case INC_OP: /* incerement operator unary so left only */
4441 fprintf(outfile,"INC_OP (%p) type (",tree);
4442 printTypeChain(tree->ftype,outfile);
4443 fprintf(outfile,")\n");
4444 ast_print(tree->left,outfile,indent+4);
4448 fprintf(outfile,"DEC_OP (%p) type (",tree);
4449 printTypeChain(tree->ftype,outfile);
4450 fprintf(outfile,")\n");
4451 ast_print(tree->left,outfile,indent+4);
4454 /*------------------------------------------------------------------*/
4455 /*----------------------------*/
4457 /*----------------------------*/
4460 fprintf(outfile,"& (%p) type (",tree);
4461 printTypeChain(tree->ftype,outfile);
4462 fprintf(outfile,")\n");
4463 ast_print(tree->left,outfile,indent+4);
4464 ast_print(tree->right,outfile,indent+4);
4466 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4467 printTypeChain(tree->ftype,outfile);
4468 fprintf(outfile,")\n");
4469 ast_print(tree->left,outfile,indent+4);
4470 ast_print(tree->right,outfile,indent+4);
4473 /*----------------------------*/
4475 /*----------------------------*/
4477 fprintf(outfile,"OR (%p) type (",tree);
4478 printTypeChain(tree->ftype,outfile);
4479 fprintf(outfile,")\n");
4480 ast_print(tree->left,outfile,indent+4);
4481 ast_print(tree->right,outfile,indent+4);
4483 /*------------------------------------------------------------------*/
4484 /*----------------------------*/
4486 /*----------------------------*/
4488 fprintf(outfile,"XOR (%p) type (",tree);
4489 printTypeChain(tree->ftype,outfile);
4490 fprintf(outfile,")\n");
4491 ast_print(tree->left,outfile,indent+4);
4492 ast_print(tree->right,outfile,indent+4);
4495 /*------------------------------------------------------------------*/
4496 /*----------------------------*/
4498 /*----------------------------*/
4500 fprintf(outfile,"DIV (%p) type (",tree);
4501 printTypeChain(tree->ftype,outfile);
4502 fprintf(outfile,")\n");
4503 ast_print(tree->left,outfile,indent+4);
4504 ast_print(tree->right,outfile,indent+4);
4506 /*------------------------------------------------------------------*/
4507 /*----------------------------*/
4509 /*----------------------------*/
4511 fprintf(outfile,"MOD (%p) type (",tree);
4512 printTypeChain(tree->ftype,outfile);
4513 fprintf(outfile,")\n");
4514 ast_print(tree->left,outfile,indent+4);
4515 ast_print(tree->right,outfile,indent+4);
4518 /*------------------------------------------------------------------*/
4519 /*----------------------------*/
4520 /* address dereference */
4521 /*----------------------------*/
4522 case '*': /* can be unary : if right is null then unary operation */
4524 fprintf(outfile,"DEREF (%p) type (",tree);
4525 printTypeChain(tree->ftype,outfile);
4526 fprintf(outfile,")\n");
4527 ast_print(tree->left,outfile,indent+4);
4530 /*------------------------------------------------------------------*/
4531 /*----------------------------*/
4532 /* multiplication */
4533 /*----------------------------*/
4534 fprintf(outfile,"MULT (%p) type (",tree);
4535 printTypeChain(tree->ftype,outfile);
4536 fprintf(outfile,")\n");
4537 ast_print(tree->left,outfile,indent+4);
4538 ast_print(tree->right,outfile,indent+4);
4542 /*------------------------------------------------------------------*/
4543 /*----------------------------*/
4544 /* unary '+' operator */
4545 /*----------------------------*/
4549 fprintf(outfile,"UPLUS (%p) type (",tree);
4550 printTypeChain(tree->ftype,outfile);
4551 fprintf(outfile,")\n");
4552 ast_print(tree->left,outfile,indent+4);
4554 /*------------------------------------------------------------------*/
4555 /*----------------------------*/
4557 /*----------------------------*/
4558 fprintf(outfile,"ADD (%p) type (",tree);
4559 printTypeChain(tree->ftype,outfile);
4560 fprintf(outfile,")\n");
4561 ast_print(tree->left,outfile,indent+4);
4562 ast_print(tree->right,outfile,indent+4);
4565 /*------------------------------------------------------------------*/
4566 /*----------------------------*/
4568 /*----------------------------*/
4569 case '-': /* can be unary */
4571 fprintf(outfile,"UMINUS (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+4);
4576 /*------------------------------------------------------------------*/
4577 /*----------------------------*/
4579 /*----------------------------*/
4580 fprintf(outfile,"SUB (%p) type (",tree);
4581 printTypeChain(tree->ftype,outfile);
4582 fprintf(outfile,")\n");
4583 ast_print(tree->left,outfile,indent+4);
4584 ast_print(tree->right,outfile,indent+4);
4587 /*------------------------------------------------------------------*/
4588 /*----------------------------*/
4590 /*----------------------------*/
4592 fprintf(outfile,"COMPL (%p) type (",tree);
4593 printTypeChain(tree->ftype,outfile);
4594 fprintf(outfile,")\n");
4595 ast_print(tree->left,outfile,indent+4);
4597 /*------------------------------------------------------------------*/
4598 /*----------------------------*/
4600 /*----------------------------*/
4602 fprintf(outfile,"NOT (%p) type (",tree);
4603 printTypeChain(tree->ftype,outfile);
4604 fprintf(outfile,")\n");
4605 ast_print(tree->left,outfile,indent+4);
4607 /*------------------------------------------------------------------*/
4608 /*----------------------------*/
4610 /*----------------------------*/
4612 fprintf(outfile,"RRC (%p) type (",tree);
4613 printTypeChain(tree->ftype,outfile);
4614 fprintf(outfile,")\n");
4615 ast_print(tree->left,outfile,indent+4);
4619 fprintf(outfile,"RLC (%p) type (",tree);
4620 printTypeChain(tree->ftype,outfile);
4621 fprintf(outfile,")\n");
4622 ast_print(tree->left,outfile,indent+4);
4625 fprintf(outfile,"GETHBIT (%p) type (",tree);
4626 printTypeChain(tree->ftype,outfile);
4627 fprintf(outfile,")\n");
4628 ast_print(tree->left,outfile,indent+4);
4631 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+4);
4635 ast_print(tree->right,outfile,indent+4);
4638 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+4);
4642 ast_print(tree->right,outfile,indent+4);
4644 /*------------------------------------------------------------------*/
4645 /*----------------------------*/
4647 /*----------------------------*/
4648 case CAST: /* change the type */
4649 fprintf(outfile,"CAST (%p) type (",tree);
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->right,outfile,indent+4);
4656 fprintf(outfile,"ANDAND (%p) type (",tree);
4657 printTypeChain(tree->ftype,outfile);
4658 fprintf(outfile,")\n");
4659 ast_print(tree->left,outfile,indent+4);
4660 ast_print(tree->right,outfile,indent+4);
4663 fprintf(outfile,"OROR (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+4);
4667 ast_print(tree->right,outfile,indent+4);
4670 /*------------------------------------------------------------------*/
4671 /*----------------------------*/
4672 /* comparison operators */
4673 /*----------------------------*/
4675 fprintf(outfile,"GT(>) (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+4);
4679 ast_print(tree->right,outfile,indent+4);
4682 fprintf(outfile,"LT(<) (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+4);
4686 ast_print(tree->right,outfile,indent+4);
4689 fprintf(outfile,"LE(<=) (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+4);
4693 ast_print(tree->right,outfile,indent+4);
4696 fprintf(outfile,"GE(>=) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+4);
4700 ast_print(tree->right,outfile,indent+4);
4703 fprintf(outfile,"EQ(==) (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+4);
4707 ast_print(tree->right,outfile,indent+4);
4710 fprintf(outfile,"NE(!=) (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+4);
4714 ast_print(tree->right,outfile,indent+4);
4715 /*------------------------------------------------------------------*/
4716 /*----------------------------*/
4718 /*----------------------------*/
4719 case SIZEOF: /* evaluate wihout code generation */
4720 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4723 /*------------------------------------------------------------------*/
4724 /*----------------------------*/
4725 /* conditional operator '?' */
4726 /*----------------------------*/
4728 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4729 printTypeChain(tree->ftype,outfile);
4730 fprintf(outfile,")\n");
4731 ast_print(tree->left,outfile,indent+4);
4732 ast_print(tree->right,outfile,indent+4);
4735 fprintf(outfile,"COLON(:) (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+4);
4739 ast_print(tree->right,outfile,indent+4);
4742 /*------------------------------------------------------------------*/
4743 /*----------------------------*/
4744 /* assignment operators */
4745 /*----------------------------*/
4747 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4748 printTypeChain(tree->ftype,outfile);
4749 fprintf(outfile,")\n");
4750 ast_print(tree->left,outfile,indent+4);
4751 ast_print(tree->right,outfile,indent+4);
4754 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4755 printTypeChain(tree->ftype,outfile);
4756 fprintf(outfile,")\n");
4757 ast_print(tree->left,outfile,indent+4);
4758 ast_print(tree->right,outfile,indent+4);
4761 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4762 printTypeChain(tree->ftype,outfile);
4763 fprintf(outfile,")\n");
4764 ast_print(tree->left,outfile,indent+4);
4765 ast_print(tree->right,outfile,indent+4);
4768 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4769 printTypeChain(tree->ftype,outfile);
4770 fprintf(outfile,")\n");
4771 ast_print(tree->left,outfile,indent+4);
4772 ast_print(tree->right,outfile,indent+4);
4775 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4776 printTypeChain(tree->ftype,outfile);
4777 fprintf(outfile,")\n");
4778 ast_print(tree->left,outfile,indent+4);
4779 ast_print(tree->right,outfile,indent+4);
4782 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4783 printTypeChain(tree->ftype,outfile);
4784 fprintf(outfile,")\n");
4785 ast_print(tree->left,outfile,indent+4);
4786 ast_print(tree->right,outfile,indent+4);
4789 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4790 printTypeChain(tree->ftype,outfile);
4791 fprintf(outfile,")\n");
4792 ast_print(tree->left,outfile,indent+4);
4793 ast_print(tree->right,outfile,indent+4);
4795 /*------------------------------------------------------------------*/
4796 /*----------------------------*/
4798 /*----------------------------*/
4800 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4801 printTypeChain(tree->ftype,outfile);
4802 fprintf(outfile,")\n");
4803 ast_print(tree->left,outfile,indent+4);
4804 ast_print(tree->right,outfile,indent+4);
4806 /*------------------------------------------------------------------*/
4807 /*----------------------------*/
4809 /*----------------------------*/
4811 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4812 printTypeChain(tree->ftype,outfile);
4813 fprintf(outfile,")\n");
4814 ast_print(tree->left,outfile,indent+4);
4815 ast_print(tree->right,outfile,indent+4);
4817 /*------------------------------------------------------------------*/
4818 /*----------------------------*/
4819 /* straight assignemnt */
4820 /*----------------------------*/
4822 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4823 printTypeChain(tree->ftype,outfile);
4824 fprintf(outfile,")\n");
4825 ast_print(tree->left,outfile,indent+4);
4826 ast_print(tree->right,outfile,indent+4);
4828 /*------------------------------------------------------------------*/
4829 /*----------------------------*/
4830 /* comma operator */
4831 /*----------------------------*/
4833 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4834 printTypeChain(tree->ftype,outfile);
4835 fprintf(outfile,")\n");
4836 ast_print(tree->left,outfile,indent+4);
4837 ast_print(tree->right,outfile,indent+4);
4839 /*------------------------------------------------------------------*/
4840 /*----------------------------*/
4842 /*----------------------------*/
4845 fprintf(outfile,"CALL (%p) type (",tree);
4846 printTypeChain(tree->ftype,outfile);
4847 fprintf(outfile,")\n");
4848 ast_print(tree->left,outfile,indent+4);
4849 ast_print(tree->right,outfile,indent+4);
4852 fprintf(outfile,"PARM ");
4853 ast_print(tree->left,outfile,indent+4);
4854 if (tree->right && !IS_AST_PARAM(tree->right)) {
4855 fprintf(outfile,"PARM ");
4856 ast_print(tree->right,outfile,indent+4);
4859 /*------------------------------------------------------------------*/
4860 /*----------------------------*/
4861 /* return statement */
4862 /*----------------------------*/
4864 fprintf(outfile,"RETURN (%p) type (",tree);
4865 printTypeChain(tree->right->ftype,outfile);
4866 fprintf(outfile,")\n");
4867 ast_print(tree->right,outfile,indent+4);
4869 /*------------------------------------------------------------------*/
4870 /*----------------------------*/
4871 /* label statement */
4872 /*----------------------------*/
4874 fprintf(outfile,"LABEL (%p)",tree);
4875 ast_print(tree->left,outfile,indent+4);
4876 ast_print(tree->right,outfile,indent);
4878 /*------------------------------------------------------------------*/
4879 /*----------------------------*/
4880 /* switch statement */
4881 /*----------------------------*/
4885 fprintf(outfile,"SWITCH (%p) ",tree);
4886 ast_print(tree->left,outfile,0);
4887 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4888 INDENT(indent+4,outfile);
4889 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4890 (int) floatFromVal(val),
4891 tree->values.switchVals.swNum,
4892 (int) floatFromVal(val));
4894 ast_print(tree->right,outfile,indent);
4897 /*------------------------------------------------------------------*/
4898 /*----------------------------*/
4900 /*----------------------------*/
4902 ast_print(tree->left,outfile,indent);
4903 INDENT(indent,outfile);
4904 fprintf(outfile,"IF (%p) \n",tree);
4905 if (tree->trueLabel) {
4906 INDENT(indent,outfile);
4907 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4909 if (tree->falseLabel) {
4910 INDENT(indent,outfile);
4911 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4913 ast_print(tree->right,outfile,indent);
4915 /*------------------------------------------------------------------*/
4916 /*----------------------------*/
4918 /*----------------------------*/
4920 fprintf(outfile,"FOR (%p) \n",tree);
4921 if (AST_FOR( tree, initExpr)) {
4922 INDENT(indent+4,outfile);
4923 fprintf(outfile,"INIT EXPR ");
4924 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4926 if (AST_FOR( tree, condExpr)) {
4927 INDENT(indent+4,outfile);
4928 fprintf(outfile,"COND EXPR ");
4929 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4931 if (AST_FOR( tree, loopExpr)) {
4932 INDENT(indent+4,outfile);
4933 fprintf(outfile,"LOOP EXPR ");
4934 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4936 fprintf(outfile,"FOR LOOP BODY \n");
4937 ast_print(tree->left,outfile,indent+4);
4946 ast_print(t,stdout,1);