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 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
51 ast *createIval (ast *, sym_link *, initList *, ast *);
52 ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 ast *optimizeRRCRLC (ast *);
54 ast *optimizeGetHbit (ast *);
55 ast *backPatchLabels (ast *, symbol *, symbol *);
57 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
62 printTypeChain (tree->ftype, stdout);
67 /*-----------------------------------------------------------------*/
68 /* newAst - creates a fresh node for an expression tree */
69 /*-----------------------------------------------------------------*/
72 newAst (int type, void *op)
75 static int oldLineno = 0;
77 ex = Safe_alloc ( sizeof (ast));
80 ex->lineno = (noLineno ? oldLineno : yylineno);
81 ex->filename = currFname;
82 ex->level = NestLevel;
83 ex->block = currBlockno;
84 ex->initMode = inInitMode;
86 /* depending on the type */
90 ex->opval.val = (value *) op;
93 ex->opval.op = (long) op;
96 ex->opval.lnk = (sym_link *) op;
99 ex->opval.stmnt = (unsigned) op;
107 newAst_ (unsigned type)
110 static int oldLineno = 0;
112 ex = Safe_alloc ( sizeof (ast));
115 ex->lineno = (noLineno ? oldLineno : yylineno);
116 ex->filename = currFname;
117 ex->level = NestLevel;
118 ex->block = currBlockno;
119 ex->initMode = inInitMode;
124 newAst_VALUE (value * val)
126 ast *ex = newAst_ (EX_VALUE);
132 newAst_OP (unsigned op)
134 ast *ex = newAst_ (EX_OP);
140 newAst_LINK (sym_link * val)
142 ast *ex = newAst_ (EX_LINK);
148 newAst_STMNT (unsigned val)
150 ast *ex = newAst_ (EX_STMNT);
151 ex->opval.stmnt = val;
155 /*-----------------------------------------------------------------*/
156 /* newNode - creates a new node */
157 /*-----------------------------------------------------------------*/
159 newNode (long op, ast * left, ast * right)
170 /*-----------------------------------------------------------------*/
171 /* newIfxNode - creates a new Ifx Node */
172 /*-----------------------------------------------------------------*/
174 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
178 /* if this is a literal then we already know the result */
179 if (condAst->etype && IS_LITERAL (condAst->etype))
181 /* then depending on the expression value */
182 if (floatFromVal (condAst->opval.val))
183 ifxNode = newNode (GOTO,
184 newAst_VALUE (symbolVal (trueLabel)),
187 ifxNode = newNode (GOTO,
188 newAst_VALUE (symbolVal (falseLabel)),
193 ifxNode = newNode (IFX, condAst, NULL);
194 ifxNode->trueLabel = trueLabel;
195 ifxNode->falseLabel = falseLabel;
201 /*-----------------------------------------------------------------*/
202 /* copyAstValues - copies value portion of ast if needed */
203 /*-----------------------------------------------------------------*/
205 copyAstValues (ast * dest, ast * src)
207 switch (src->opval.op)
210 dest->values.sym = copySymbolChain (src->values.sym);
214 dest->values.switchVals.swVals =
215 copyValue (src->values.switchVals.swVals);
216 dest->values.switchVals.swDefault =
217 src->values.switchVals.swDefault;
218 dest->values.switchVals.swNum =
219 src->values.switchVals.swNum;
223 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
224 strcpy (dest->values.inlineasm, src->values.inlineasm);
228 dest->values.constlist = copyLiteralList(src->values.constlist);
232 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
233 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
234 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
235 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
236 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
237 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
238 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
243 /*-----------------------------------------------------------------*/
244 /* copyAst - makes a copy of a given astession */
245 /*-----------------------------------------------------------------*/
254 dest = Safe_alloc ( sizeof (ast));
256 dest->type = src->type;
257 dest->lineno = src->lineno;
258 dest->level = src->level;
259 dest->funcName = src->funcName;
260 dest->argSym = src->argSym;
262 /* if this is a leaf */
264 if (src->type == EX_VALUE)
266 dest->opval.val = copyValue (src->opval.val);
271 if (src->type == EX_LINK)
273 dest->opval.lnk = copyLinkChain (src->opval.lnk);
277 dest->opval.op = src->opval.op;
279 /* if this is a node that has special values */
280 copyAstValues (dest, src);
283 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
285 dest->trueLabel = copySymbol (src->trueLabel);
286 dest->falseLabel = copySymbol (src->falseLabel);
287 dest->left = copyAst (src->left);
288 dest->right = copyAst (src->right);
294 /*-----------------------------------------------------------------*/
295 /* hasSEFcalls - returns TRUE if tree has a function call */
296 /*-----------------------------------------------------------------*/
298 hasSEFcalls (ast * tree)
303 if (tree->type == EX_OP &&
304 (tree->opval.op == CALL ||
305 tree->opval.op == PCALL ||
306 tree->opval.op == '=' ||
307 tree->opval.op == INC_OP ||
308 tree->opval.op == DEC_OP))
311 return (hasSEFcalls (tree->left) |
312 hasSEFcalls (tree->right));
315 /*-----------------------------------------------------------------*/
316 /* isAstEqual - compares two asts & returns 1 if they are equal */
317 /*-----------------------------------------------------------------*/
319 isAstEqual (ast * t1, ast * t2)
328 if (t1->type != t2->type)
334 if (t1->opval.op != t2->opval.op)
336 return (isAstEqual (t1->left, t2->left) &&
337 isAstEqual (t1->right, t2->right));
341 if (t1->opval.val->sym)
343 if (!t2->opval.val->sym)
346 return isSymbolEqual (t1->opval.val->sym,
351 if (t2->opval.val->sym)
354 return (floatFromVal (t1->opval.val) ==
355 floatFromVal (t2->opval.val));
359 /* only compare these two types */
367 /*-----------------------------------------------------------------*/
368 /* resolveSymbols - resolve symbols from the symbol table */
369 /*-----------------------------------------------------------------*/
371 resolveSymbols (ast * tree)
373 /* walk the entire tree and check for values */
374 /* with symbols if we find one then replace */
375 /* symbol with that from the symbol table */
381 /* if not block & function */
382 if (tree->type == EX_OP &&
383 (tree->opval.op != FUNCTION &&
384 tree->opval.op != BLOCK &&
385 tree->opval.op != NULLOP))
387 filename = tree->filename;
388 lineno = tree->lineno;
391 /* make sure we resolve the true & false labels for ifx */
392 if (tree->type == EX_OP && tree->opval.op == IFX)
398 if ((csym = findSym (LabelTab, tree->trueLabel,
399 tree->trueLabel->name)))
400 tree->trueLabel = csym;
402 werror (E_LABEL_UNDEF, tree->trueLabel->name);
405 if (tree->falseLabel)
407 if ((csym = findSym (LabelTab,
409 tree->falseLabel->name)))
410 tree->falseLabel = csym;
412 werror (E_LABEL_UNDEF, tree->falseLabel->name);
417 /* if this is a label resolve it from the labelTab */
418 if (IS_AST_VALUE (tree) &&
419 tree->opval.val->sym &&
420 tree->opval.val->sym->islbl)
423 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
424 tree->opval.val->sym->name);
427 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
429 tree->opval.val->sym = csym;
431 goto resolveChildren;
434 /* do only for leafs */
435 if (IS_AST_VALUE (tree) &&
436 tree->opval.val->sym &&
437 !tree->opval.val->sym->implicit)
440 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
442 /* if found in the symbol table & they r not the same */
443 if (csym && tree->opval.val->sym != csym)
445 tree->opval.val->sym = csym;
446 tree->opval.val->type = csym->type;
447 tree->opval.val->etype = csym->etype;
450 /* if not found in the symbol table */
451 /* mark it as undefined assume it is */
452 /* an integer in data space */
453 if (!csym && !tree->opval.val->sym->implicit)
456 /* if this is a function name then */
457 /* mark it as returning an int */
460 tree->opval.val->sym->type = newLink ();
461 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
462 tree->opval.val->sym->type->next =
463 tree->opval.val->sym->etype = newIntLink ();
464 tree->opval.val->etype = tree->opval.val->etype;
465 tree->opval.val->type = tree->opval.val->sym->type;
466 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
467 allocVariables (tree->opval.val->sym);
471 tree->opval.val->sym->undefined = 1;
472 tree->opval.val->type =
473 tree->opval.val->etype = newIntLink ();
474 tree->opval.val->sym->type =
475 tree->opval.val->sym->etype = newIntLink ();
481 resolveSymbols (tree->left);
482 resolveSymbols (tree->right);
487 /*-----------------------------------------------------------------*/
488 /* setAstLineno - walks a ast tree & sets the line number */
489 /*-----------------------------------------------------------------*/
491 setAstLineno (ast * tree, int lineno)
496 tree->lineno = lineno;
497 setAstLineno (tree->left, lineno);
498 setAstLineno (tree->right, lineno);
503 /* this functions seems to be superfluous?! kmh */
505 /*-----------------------------------------------------------------*/
506 /* resolveFromTable - will return the symbal table value */
507 /*-----------------------------------------------------------------*/
509 resolveFromTable (value * val)
516 csym = findSymWithLevel (SymbolTab, val->sym);
518 /* if found in the symbol table & they r not the same */
519 if (csym && val->sym != csym &&
520 csym->level == val->sym->level &&
526 val->type = csym->type;
527 val->etype = csym->etype;
534 /*-----------------------------------------------------------------*/
535 /* funcOfType :- function of type with name */
536 /*-----------------------------------------------------------------*/
538 funcOfType (char *name, sym_link * type, sym_link * argType,
542 /* create the symbol */
543 sym = newSymbol (name, 0);
545 /* if arguments required */
550 args = sym->args = newValue ();
554 args->type = copyLinkChain (argType);
555 args->etype = getSpec (args->type);
558 args = args->next = newValue ();
562 /* setup return value */
563 sym->type = newLink ();
564 DCL_TYPE (sym->type) = FUNCTION;
565 sym->type->next = copyLinkChain (type);
566 sym->etype = getSpec (sym->type);
567 SPEC_RENT (sym->etype) = rent;
572 allocVariables (sym);
577 /*-----------------------------------------------------------------*/
578 /* reverseParms - will reverse a parameter tree */
579 /*-----------------------------------------------------------------*/
581 reverseParms (ast * ptree)
587 /* top down if we find a nonParm tree then quit */
588 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
591 ptree->left = ptree->right;
592 ptree->right = ttree;
593 reverseParms (ptree->left);
594 reverseParms (ptree->right);
600 /*-----------------------------------------------------------------*/
601 /* processParms - makes sure the parameters are okay and do some */
602 /* processing with them */
603 /*-----------------------------------------------------------------*/
605 processParms (ast * func,
608 int *parmNumber, // unused, although updated
609 bool rightmost) // double checked?
611 sym_link *fetype = func->etype;
613 /* if none of them exist */
614 if (!defParm && !actParm)
618 if (getenv("DEBUG_SANITY")) {
619 fprintf (stderr, "processParms: %s ", defParm->name);
621 /* make sure the type is complete and sane */
622 checkTypeSanity(defParm->etype, defParm->name);
625 /* if the function is being called via a pointer & */
626 /* it has not been defined a reentrant then we cannot */
627 /* have parameters */
628 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
630 werror (W_NONRENT_ARGS);
634 /* if defined parameters ended but actual parameters */
635 /* exist and this is not defined as a variable arg */
636 /* also check if statckAuto option is specified */ // jwk: WHY?
637 if ((!defParm) && actParm && (!func->hasVargs)
638 /* && !options.stackAuto && !IS_RENT (fetype) */)
640 werror (E_TOO_MANY_PARMS);
644 /* if defined parameters present but no actual parameters */
645 if (defParm && !actParm)
647 werror (E_TOO_FEW_PARMS);
651 /* If this is a varargs function... */
652 if (!defParm && actParm && func->hasVargs)
657 if (IS_CAST_OP (actParm)
658 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
660 /* Parameter was explicitly typecast; don't touch it. */
664 /* The ternary ('?') operator is weird: the ftype of the
665 * operator is the type of the condition, but it will return a
666 * (possibly) different type.
668 if (IS_TERNARY_OP(actParm))
670 assert(IS_COLON_OP(actParm->right));
671 assert(actParm->right->left);
672 ftype = actParm->right->left->ftype;
676 ftype = actParm->ftype;
679 /* If it's a small integer, upcast to int. */
680 if (IS_INTEGRAL (ftype)
681 && (getSize (ftype) < (unsigned) INTSIZE))
683 newType = newAst_LINK(INTTYPE);
686 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
688 newType = newAst_LINK (copyLinkChain(ftype));
689 DCL_TYPE (newType->opval.lnk) = GPOINTER;
692 if (IS_AGGREGATE (ftype))
694 newType = newAst_LINK (copyLinkChain (ftype));
695 DCL_TYPE (newType->opval.lnk) = GPOINTER;
699 /* cast required; change this op to a cast. */
700 ast *parmCopy = resolveSymbols (copyAst (actParm));
702 actParm->type = EX_OP;
703 actParm->opval.op = CAST;
704 actParm->left = newType;
705 actParm->right = parmCopy;
706 decorateType (actParm);
708 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
710 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
711 processParms (func, NULL, actParm->right, parmNumber, rightmost));
716 /* if defined parameters ended but actual has not & */
718 if (!defParm && actParm &&
719 (options.stackAuto || IS_RENT (fetype)))
722 resolveSymbols (actParm);
723 /* if this is a PARAM node then match left & right */
724 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
726 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
727 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
731 /* If we have found a value node by following only right-hand links,
732 * then we know that there are no more values after us.
734 * Therefore, if there are more defined parameters, the caller didn't
737 if (rightmost && defParm->next)
739 werror (E_TOO_FEW_PARMS);
744 /* the parameter type must be at least castable */
745 if (compareType (defParm->type, actParm->ftype) == 0) {
746 werror (E_INCOMPAT_TYPES);
747 fprintf (stderr, "type --> '");
748 printTypeChain (actParm->ftype, stderr);
749 fprintf (stderr, "' ");
750 fprintf (stderr, "assigned to type --> '");
751 printTypeChain (defParm->type, stderr);
752 fprintf (stderr, "'\n");
756 /* if the parameter is castable then add the cast */
757 if (compareType (defParm->type, actParm->ftype) < 0)
759 ast *pTree = resolveSymbols (copyAst (actParm));
761 /* now change the current one to a cast */
762 actParm->type = EX_OP;
763 actParm->opval.op = CAST;
764 actParm->left = newAst_LINK (defParm->type);
765 actParm->right = pTree;
766 actParm->etype = defParm->etype;
767 actParm->ftype = defParm->type;
770 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
772 actParm->argSym = defParm->sym;
773 /* make a copy and change the regparm type to the defined parm */
774 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
775 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
779 /*-----------------------------------------------------------------*/
780 /* createIvalType - generates ival for basic types */
781 /*-----------------------------------------------------------------*/
783 createIvalType (ast * sym, sym_link * type, initList * ilist)
787 /* if initList is deep */
788 if (ilist->type == INIT_DEEP)
789 ilist = ilist->init.deep;
791 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
792 return decorateType (newNode ('=', sym, iExpr));
795 /*-----------------------------------------------------------------*/
796 /* createIvalStruct - generates initial value for structures */
797 /*-----------------------------------------------------------------*/
799 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
805 sflds = SPEC_STRUCT (type)->fields;
806 if (ilist->type != INIT_DEEP)
808 werror (E_INIT_STRUCT, "");
812 iloop = ilist->init.deep;
814 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
818 /* if we have come to end */
822 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
823 lAst = decorateType (resolveSymbols (lAst));
824 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
830 /*-----------------------------------------------------------------*/
831 /* createIvalArray - generates code for array initialization */
832 /*-----------------------------------------------------------------*/
834 createIvalArray (ast * sym, sym_link * type, initList * ilist)
838 int lcnt = 0, size = 0;
839 literalList *literalL;
841 /* take care of the special case */
842 /* array of characters can be init */
844 if (IS_CHAR (type->next))
845 if ((rast = createIvalCharPtr (sym,
847 decorateType (resolveSymbols (list2expr (ilist))))))
849 return decorateType (resolveSymbols (rast));
851 /* not the special case */
852 if (ilist->type != INIT_DEEP)
854 werror (E_INIT_STRUCT, "");
858 iloop = ilist->init.deep;
859 lcnt = DCL_ELEM (type);
861 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
865 aSym = decorateType (resolveSymbols(sym));
867 rast = newNode(ARRAYINIT, aSym, NULL);
868 rast->values.constlist = literalL;
870 // Make sure size is set to length of initializer list.
877 if (lcnt && size > lcnt)
879 // Array size was specified, and we have more initializers than needed.
880 char *name=sym->opval.val->sym->name;
881 int lineno=sym->opval.val->sym->lineDef;
883 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
892 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
893 aSym = decorateType (resolveSymbols (aSym));
894 rast = createIval (aSym, type->next, iloop, rast);
895 iloop = (iloop ? iloop->next : NULL);
901 /* no of elements given and we */
902 /* have generated for all of them */
905 // there has to be a better way
906 char *name=sym->opval.val->sym->name;
907 int lineno=sym->opval.val->sym->lineDef;
908 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
915 /* if we have not been given a size */
916 if (!DCL_ELEM (type))
918 DCL_ELEM (type) = size;
921 return decorateType (resolveSymbols (rast));
925 /*-----------------------------------------------------------------*/
926 /* createIvalCharPtr - generates initial values for char pointers */
927 /*-----------------------------------------------------------------*/
929 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
933 /* if this is a pointer & right is a literal array then */
934 /* just assignment will do */
935 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
936 SPEC_SCLS (iexpr->etype) == S_CODE)
937 && IS_ARRAY (iexpr->ftype)))
938 return newNode ('=', sym, iexpr);
940 /* left side is an array so we have to assign each */
942 if ((IS_LITERAL (iexpr->etype) ||
943 SPEC_SCLS (iexpr->etype) == S_CODE)
944 && IS_ARRAY (iexpr->ftype))
946 /* for each character generate an assignment */
947 /* to the array element */
948 char *s = SPEC_CVAL (iexpr->etype).v_char;
953 rast = newNode (NULLOP,
957 newAst_VALUE (valueFromLit ((float) i))),
958 newAst_VALUE (valueFromLit (*s))));
962 rast = newNode (NULLOP,
966 newAst_VALUE (valueFromLit ((float) i))),
967 newAst_VALUE (valueFromLit (*s))));
968 return decorateType (resolveSymbols (rast));
974 /*-----------------------------------------------------------------*/
975 /* createIvalPtr - generates initial value for pointers */
976 /*-----------------------------------------------------------------*/
978 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
984 if (ilist->type == INIT_DEEP)
985 ilist = ilist->init.deep;
987 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
989 /* if character pointer */
990 if (IS_CHAR (type->next))
991 if ((rast = createIvalCharPtr (sym, type, iexpr)))
994 return newNode ('=', sym, iexpr);
997 /*-----------------------------------------------------------------*/
998 /* createIval - generates code for initial value */
999 /*-----------------------------------------------------------------*/
1001 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1008 /* if structure then */
1009 if (IS_STRUCT (type))
1010 rast = createIvalStruct (sym, type, ilist);
1012 /* if this is a pointer */
1014 rast = createIvalPtr (sym, type, ilist);
1016 /* if this is an array */
1017 if (IS_ARRAY (type))
1018 rast = createIvalArray (sym, type, ilist);
1020 /* if type is SPECIFIER */
1022 rast = createIvalType (sym, type, ilist);
1025 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1027 return decorateType (resolveSymbols (rast));
1030 /*-----------------------------------------------------------------*/
1031 /* initAggregates - initialises aggregate variables with initv */
1032 /*-----------------------------------------------------------------*/
1034 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1036 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1040 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1042 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1043 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1044 "with -mmcs51 and --model-large");
1048 if (SPEC_OCLS(sym->etype)==xdata &&
1049 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1052 newSym=copySymbol (sym);
1053 SPEC_OCLS(newSym->etype)=code;
1054 sprintf (newSym->name, "%s_init__", sym->name);
1055 sprintf (newSym->rname,"%s_init__", sym->rname);
1056 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1058 // emit it in the static segment
1059 addSet(&statsg->syms, newSym);
1061 // now memcpy() the entire array from cseg
1062 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1063 newAst_VALUE (symbolVal (sym)),
1064 newAst_VALUE (symbolVal (newSym)));
1065 return decorateType(resolveSymbols(ast));
1069 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1072 /*-----------------------------------------------------------------*/
1073 /* gatherAutoInit - creates assignment expressions for initial */
1075 /*-----------------------------------------------------------------*/
1077 gatherAutoInit (symbol * autoChain)
1084 for (sym = autoChain; sym; sym = sym->next)
1087 /* resolve the symbols in the ival */
1089 resolveIvalSym (sym->ival);
1091 /* if this is a static variable & has an */
1092 /* initial value the code needs to be lifted */
1093 /* here to the main portion since they can be */
1094 /* initialised only once at the start */
1095 if (IS_STATIC (sym->etype) && sym->ival &&
1096 SPEC_SCLS (sym->etype) != S_CODE)
1100 // this can only be a constant
1101 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1102 werror (E_CONST_EXPECTED);
1105 /* insert the symbol into the symbol table */
1106 /* with level = 0 & name = rname */
1107 newSym = copySymbol (sym);
1108 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1110 /* now lift the code to main */
1111 if (IS_AGGREGATE (sym->type))
1112 work = initAggregates (sym, sym->ival, NULL);
1114 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1115 list2expr (sym->ival));
1117 setAstLineno (work, sym->lineDef);
1121 staticAutos = newNode (NULLOP, staticAutos, work);
1128 /* if there is an initial value */
1129 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1131 if (IS_AGGREGATE (sym->type))
1132 work = initAggregates (sym, sym->ival, NULL);
1134 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1135 list2expr (sym->ival));
1137 setAstLineno (work, sym->lineDef);
1140 init = newNode (NULLOP, init, work);
1149 /*-----------------------------------------------------------------*/
1150 /* stringToSymbol - creates a symbol from a literal string */
1151 /*-----------------------------------------------------------------*/
1153 stringToSymbol (value * val)
1155 char name[SDCC_NAME_MAX + 1];
1156 static int charLbl = 0;
1159 sprintf (name, "_str_%d", charLbl++);
1160 sym = newSymbol (name, 0); /* make it @ level 0 */
1161 strcpy (sym->rname, name);
1163 /* copy the type from the value passed */
1164 sym->type = copyLinkChain (val->type);
1165 sym->etype = getSpec (sym->type);
1166 /* change to storage class & output class */
1167 SPEC_SCLS (sym->etype) = S_CODE;
1168 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1169 SPEC_STAT (sym->etype) = 1;
1170 /* make the level & block = 0 */
1171 sym->block = sym->level = 0;
1173 /* create an ival */
1174 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1179 allocVariables (sym);
1182 return symbolVal (sym);
1186 /*-----------------------------------------------------------------*/
1187 /* processBlockVars - will go thru the ast looking for block if */
1188 /* a block is found then will allocate the syms */
1189 /* will also gather the auto inits present */
1190 /*-----------------------------------------------------------------*/
1192 processBlockVars (ast * tree, int *stack, int action)
1197 /* if this is a block */
1198 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1202 if (action == ALLOCATE)
1204 *stack += allocVariables (tree->values.sym);
1205 autoInit = gatherAutoInit (tree->values.sym);
1207 /* if there are auto inits then do them */
1209 tree->left = newNode (NULLOP, autoInit, tree->left);
1211 else /* action is deallocate */
1212 deallocLocal (tree->values.sym);
1215 processBlockVars (tree->left, stack, action);
1216 processBlockVars (tree->right, stack, action);
1220 /*-----------------------------------------------------------------*/
1221 /* constExprValue - returns the value of a constant expression */
1222 /* or NULL if it is not a constant expression */
1223 /*-----------------------------------------------------------------*/
1225 constExprValue (ast * cexpr, int check)
1227 cexpr = decorateType (resolveSymbols (cexpr));
1229 /* if this is not a constant then */
1230 if (!IS_LITERAL (cexpr->ftype))
1232 /* then check if this is a literal array
1234 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1235 SPEC_CVAL (cexpr->etype).v_char &&
1236 IS_ARRAY (cexpr->ftype))
1238 value *val = valFromType (cexpr->ftype);
1239 SPEC_SCLS (val->etype) = S_LITERAL;
1240 val->sym = cexpr->opval.val->sym;
1241 val->sym->type = copyLinkChain (cexpr->ftype);
1242 val->sym->etype = getSpec (val->sym->type);
1243 strcpy (val->name, cexpr->opval.val->sym->rname);
1247 /* if we are casting a literal value then */
1248 if (IS_AST_OP (cexpr) &&
1249 cexpr->opval.op == CAST &&
1250 IS_LITERAL (cexpr->left->ftype))
1251 return valCastLiteral (cexpr->ftype,
1252 floatFromVal (cexpr->left->opval.val));
1254 if (IS_AST_VALUE (cexpr))
1255 return cexpr->opval.val;
1258 werror (E_CONST_EXPECTED, "found expression");
1263 /* return the value */
1264 return cexpr->opval.val;
1268 /*-----------------------------------------------------------------*/
1269 /* isLabelInAst - will return true if a given label is found */
1270 /*-----------------------------------------------------------------*/
1272 isLabelInAst (symbol * label, ast * tree)
1274 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1277 if (IS_AST_OP (tree) &&
1278 tree->opval.op == LABEL &&
1279 isSymbolEqual (AST_SYMBOL (tree->left), label))
1282 return isLabelInAst (label, tree->right) &&
1283 isLabelInAst (label, tree->left);
1287 /*-----------------------------------------------------------------*/
1288 /* isLoopCountable - return true if the loop count can be determi- */
1289 /* -ned at compile time . */
1290 /*-----------------------------------------------------------------*/
1292 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1293 symbol ** sym, ast ** init, ast ** end)
1296 /* the loop is considered countable if the following
1297 conditions are true :-
1299 a) initExpr :- <sym> = <const>
1300 b) condExpr :- <sym> < <const1>
1301 c) loopExpr :- <sym> ++
1304 /* first check the initExpr */
1305 if (IS_AST_OP (initExpr) &&
1306 initExpr->opval.op == '=' && /* is assignment */
1307 IS_AST_SYM_VALUE (initExpr->left))
1308 { /* left is a symbol */
1310 *sym = AST_SYMBOL (initExpr->left);
1311 *init = initExpr->right;
1316 /* for now the symbol has to be of
1318 if (!IS_INTEGRAL ((*sym)->type))
1321 /* now check condExpr */
1322 if (IS_AST_OP (condExpr))
1325 switch (condExpr->opval.op)
1328 if (IS_AST_SYM_VALUE (condExpr->left) &&
1329 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1330 IS_AST_LIT_VALUE (condExpr->right))
1332 *end = condExpr->right;
1338 if (IS_AST_OP (condExpr->left) &&
1339 condExpr->left->opval.op == '>' &&
1340 IS_AST_LIT_VALUE (condExpr->left->right) &&
1341 IS_AST_SYM_VALUE (condExpr->left->left) &&
1342 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1345 *end = newNode ('+', condExpr->left->right,
1346 newAst_VALUE (constVal ("1")));
1357 /* check loop expression is of the form <sym>++ */
1358 if (!IS_AST_OP (loopExpr))
1361 /* check if <sym> ++ */
1362 if (loopExpr->opval.op == INC_OP)
1368 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1369 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1376 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1377 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1385 if (loopExpr->opval.op == ADD_ASSIGN)
1388 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1389 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1390 IS_AST_LIT_VALUE (loopExpr->right) &&
1391 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1399 /*-----------------------------------------------------------------*/
1400 /* astHasVolatile - returns true if ast contains any volatile */
1401 /*-----------------------------------------------------------------*/
1403 astHasVolatile (ast * tree)
1408 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1411 if (IS_AST_OP (tree))
1412 return astHasVolatile (tree->left) ||
1413 astHasVolatile (tree->right);
1418 /*-----------------------------------------------------------------*/
1419 /* astHasPointer - return true if the ast contains any ptr variable */
1420 /*-----------------------------------------------------------------*/
1422 astHasPointer (ast * tree)
1427 if (IS_AST_LINK (tree))
1430 /* if we hit an array expression then check
1431 only the left side */
1432 if (IS_AST_OP (tree) && tree->opval.op == '[')
1433 return astHasPointer (tree->left);
1435 if (IS_AST_VALUE (tree))
1436 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1438 return astHasPointer (tree->left) ||
1439 astHasPointer (tree->right);
1443 /*-----------------------------------------------------------------*/
1444 /* astHasSymbol - return true if the ast has the given symbol */
1445 /*-----------------------------------------------------------------*/
1447 astHasSymbol (ast * tree, symbol * sym)
1449 if (!tree || IS_AST_LINK (tree))
1452 if (IS_AST_VALUE (tree))
1454 if (IS_AST_SYM_VALUE (tree))
1455 return isSymbolEqual (AST_SYMBOL (tree), sym);
1460 return astHasSymbol (tree->left, sym) ||
1461 astHasSymbol (tree->right, sym);
1464 /*-----------------------------------------------------------------*/
1465 /* astHasDeref - return true if the ast has an indirect access */
1466 /*-----------------------------------------------------------------*/
1468 astHasDeref (ast * tree)
1470 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1473 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1475 return astHasDeref (tree->left) || astHasDeref (tree->right);
1478 /*-----------------------------------------------------------------*/
1479 /* isConformingBody - the loop body has to conform to a set of rules */
1480 /* for the loop to be considered reversible read on for rules */
1481 /*-----------------------------------------------------------------*/
1483 isConformingBody (ast * pbody, symbol * sym, ast * body)
1486 /* we are going to do a pre-order traversal of the
1487 tree && check for the following conditions. (essentially
1488 a set of very shallow tests )
1489 a) the sym passed does not participate in
1490 any arithmetic operation
1491 b) There are no function calls
1492 c) all jumps are within the body
1493 d) address of loop control variable not taken
1494 e) if an assignment has a pointer on the
1495 left hand side make sure right does not have
1496 loop control variable */
1498 /* if we reach the end or a leaf then true */
1499 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1503 /* if anything else is "volatile" */
1504 if (IS_VOLATILE (TETYPE (pbody)))
1507 /* we will walk the body in a pre-order traversal for
1509 switch (pbody->opval.op)
1511 /*------------------------------------------------------------------*/
1513 return isConformingBody (pbody->right, sym, body);
1515 /*------------------------------------------------------------------*/
1520 /*------------------------------------------------------------------*/
1521 case INC_OP: /* incerement operator unary so left only */
1524 /* sure we are not sym is not modified */
1526 IS_AST_SYM_VALUE (pbody->left) &&
1527 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1531 IS_AST_SYM_VALUE (pbody->right) &&
1532 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1537 /*------------------------------------------------------------------*/
1539 case '*': /* can be unary : if right is null then unary operation */
1544 /* if right is NULL then unary operation */
1545 /*------------------------------------------------------------------*/
1546 /*----------------------------*/
1548 /*----------------------------*/
1551 if (IS_AST_SYM_VALUE (pbody->left) &&
1552 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1555 return isConformingBody (pbody->left, sym, body);
1559 if (astHasSymbol (pbody->left, sym) ||
1560 astHasSymbol (pbody->right, sym))
1565 /*------------------------------------------------------------------*/
1573 if (IS_AST_SYM_VALUE (pbody->left) &&
1574 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1577 if (IS_AST_SYM_VALUE (pbody->right) &&
1578 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1581 return isConformingBody (pbody->left, sym, body) &&
1582 isConformingBody (pbody->right, sym, body);
1589 if (IS_AST_SYM_VALUE (pbody->left) &&
1590 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1592 return isConformingBody (pbody->left, sym, body);
1594 /*------------------------------------------------------------------*/
1606 case SIZEOF: /* evaluate wihout code generation */
1608 return isConformingBody (pbody->left, sym, body) &&
1609 isConformingBody (pbody->right, sym, body);
1611 /*------------------------------------------------------------------*/
1614 /* if left has a pointer & right has loop
1615 control variable then we cannot */
1616 if (astHasPointer (pbody->left) &&
1617 astHasSymbol (pbody->right, sym))
1619 if (astHasVolatile (pbody->left))
1622 if (IS_AST_SYM_VALUE (pbody->left) &&
1623 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1626 if (astHasVolatile (pbody->left))
1629 if (astHasDeref(pbody->right)) return FALSE;
1631 return isConformingBody (pbody->left, sym, body) &&
1632 isConformingBody (pbody->right, sym, body);
1643 assert ("Parser should not have generated this\n");
1645 /*------------------------------------------------------------------*/
1646 /*----------------------------*/
1647 /* comma operator */
1648 /*----------------------------*/
1650 return isConformingBody (pbody->left, sym, body) &&
1651 isConformingBody (pbody->right, sym, body);
1653 /*------------------------------------------------------------------*/
1654 /*----------------------------*/
1656 /*----------------------------*/
1660 /*------------------------------------------------------------------*/
1661 /*----------------------------*/
1662 /* return statement */
1663 /*----------------------------*/
1668 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1673 if (astHasSymbol (pbody->left, sym))
1680 return isConformingBody (pbody->left, sym, body) &&
1681 isConformingBody (pbody->right, sym, body);
1687 /*-----------------------------------------------------------------*/
1688 /* isLoopReversible - takes a for loop as input && returns true */
1689 /* if the for loop is reversible. If yes will set the value of */
1690 /* the loop control var & init value & termination value */
1691 /*-----------------------------------------------------------------*/
1693 isLoopReversible (ast * loop, symbol ** loopCntrl,
1694 ast ** init, ast ** end)
1696 /* if option says don't do it then don't */
1697 if (optimize.noLoopReverse)
1699 /* there are several tests to determine this */
1701 /* for loop has to be of the form
1702 for ( <sym> = <const1> ;
1703 [<sym> < <const2>] ;
1704 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1706 if (!isLoopCountable (AST_FOR (loop, initExpr),
1707 AST_FOR (loop, condExpr),
1708 AST_FOR (loop, loopExpr),
1709 loopCntrl, init, end))
1712 /* now do some serious checking on the body of the loop
1715 return isConformingBody (loop->left, *loopCntrl, loop->left);
1719 /*-----------------------------------------------------------------*/
1720 /* replLoopSym - replace the loop sym by loop sym -1 */
1721 /*-----------------------------------------------------------------*/
1723 replLoopSym (ast * body, symbol * sym)
1726 if (!body || IS_AST_LINK (body))
1729 if (IS_AST_SYM_VALUE (body))
1732 if (isSymbolEqual (AST_SYMBOL (body), sym))
1736 body->opval.op = '-';
1737 body->left = newAst_VALUE (symbolVal (sym));
1738 body->right = newAst_VALUE (constVal ("1"));
1746 replLoopSym (body->left, sym);
1747 replLoopSym (body->right, sym);
1751 /*-----------------------------------------------------------------*/
1752 /* reverseLoop - do the actual loop reversal */
1753 /*-----------------------------------------------------------------*/
1755 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1759 /* create the following tree
1764 if (sym) goto for_continue ;
1767 /* put it together piece by piece */
1768 rloop = newNode (NULLOP,
1769 createIf (newAst_VALUE (symbolVal (sym)),
1771 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1774 newAst_VALUE (symbolVal (sym)),
1777 replLoopSym (loop->left, sym);
1779 rloop = newNode (NULLOP,
1781 newAst_VALUE (symbolVal (sym)),
1782 newNode ('-', end, init)),
1783 createLabel (AST_FOR (loop, continueLabel),
1787 newNode (SUB_ASSIGN,
1788 newAst_VALUE (symbolVal (sym)),
1789 newAst_VALUE (constVal ("1"))),
1792 return decorateType (rloop);
1796 //#define DEMAND_INTEGER_PROMOTION
1798 #ifdef DEMAND_INTEGER_PROMOTION
1800 /*-----------------------------------------------------------------*/
1801 /* walk a tree looking for the leaves. Add a typecast to the given */
1802 /* type to each value leaf node. */
1803 /*-----------------------------------------------------------------*/
1805 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1807 if (!node || IS_CALLOP(node))
1809 /* WTF? We should never get here. */
1813 if (!node->left && !node->right)
1815 /* We're at a leaf; if it's a value, apply the typecast */
1816 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1818 *parentPtr = decorateType (newNode (CAST,
1819 newAst_LINK (copyLinkChain (type)),
1827 pushTypeCastToLeaves (type, node->left, &(node->left));
1831 pushTypeCastToLeaves (type, node->right, &(node->right));
1838 /*-----------------------------------------------------------------*/
1839 /* Given an assignment operation in a tree, determine if the LHS */
1840 /* (the result) has a different (integer) type than the RHS. */
1841 /* If so, walk the RHS and add a typecast to the type of the LHS */
1842 /* to all leaf nodes. */
1843 /*-----------------------------------------------------------------*/
1845 propAsgType (ast * tree)
1847 #ifdef DEMAND_INTEGER_PROMOTION
1848 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1850 /* Nothing to do here... */
1854 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1856 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1863 /*-----------------------------------------------------------------*/
1864 /* decorateType - compute type for this tree also does type cheking */
1865 /* this is done bottom up, since type have to flow upwards */
1866 /* it also does constant folding, and paramater checking */
1867 /*-----------------------------------------------------------------*/
1869 decorateType (ast * tree)
1877 /* if already has type then do nothing */
1878 if (tree->decorated)
1881 tree->decorated = 1;
1883 /* print the line */
1884 /* if not block & function */
1885 if (tree->type == EX_OP &&
1886 (tree->opval.op != FUNCTION &&
1887 tree->opval.op != BLOCK &&
1888 tree->opval.op != NULLOP))
1890 filename = tree->filename;
1891 lineno = tree->lineno;
1894 /* if any child is an error | this one is an error do nothing */
1895 if (tree->isError ||
1896 (tree->left && tree->left->isError) ||
1897 (tree->right && tree->right->isError))
1900 /*------------------------------------------------------------------*/
1901 /*----------------------------*/
1902 /* leaf has been reached */
1903 /*----------------------------*/
1904 /* if this is of type value */
1905 /* just get the type */
1906 if (tree->type == EX_VALUE)
1909 if (IS_LITERAL (tree->opval.val->etype))
1912 /* if this is a character array then declare it */
1913 if (IS_ARRAY (tree->opval.val->type))
1914 tree->opval.val = stringToSymbol (tree->opval.val);
1916 /* otherwise just copy the type information */
1917 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1918 if (funcInChain (tree->opval.val->type))
1920 tree->hasVargs = tree->opval.val->sym->hasVargs;
1921 tree->args = copyValueChain (tree->opval.val->sym->args);
1926 if (tree->opval.val->sym)
1928 /* if the undefined flag is set then give error message */
1929 if (tree->opval.val->sym->undefined)
1931 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1933 TTYPE (tree) = TETYPE (tree) =
1934 tree->opval.val->type = tree->opval.val->sym->type =
1935 tree->opval.val->etype = tree->opval.val->sym->etype =
1936 copyLinkChain (INTTYPE);
1941 /* if impilicit i.e. struct/union member then no type */
1942 if (tree->opval.val->sym->implicit)
1943 TTYPE (tree) = TETYPE (tree) = NULL;
1948 /* else copy the type */
1949 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1951 /* and mark it as referenced */
1952 tree->opval.val->sym->isref = 1;
1953 /* if this is of type function or function pointer */
1954 if (funcInChain (tree->opval.val->type))
1956 tree->hasVargs = tree->opval.val->sym->hasVargs;
1957 tree->args = copyValueChain (tree->opval.val->sym->args);
1967 /* if type link for the case of cast */
1968 if (tree->type == EX_LINK)
1970 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1977 dtl = decorateType (tree->left);
1978 dtr = decorateType (tree->right);
1980 /* this is to take care of situations
1981 when the tree gets rewritten */
1982 if (dtl != tree->left)
1984 if (dtr != tree->right)
1988 /* depending on type of operator do */
1990 switch (tree->opval.op)
1992 /*------------------------------------------------------------------*/
1993 /*----------------------------*/
1995 /*----------------------------*/
1998 /* determine which is the array & which the index */
1999 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2002 ast *tempTree = tree->left;
2003 tree->left = tree->right;
2004 tree->right = tempTree;
2007 /* first check if this is a array or a pointer */
2008 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2010 werror (E_NEED_ARRAY_PTR, "[]");
2011 goto errorTreeReturn;
2014 /* check if the type of the idx */
2015 if (!IS_INTEGRAL (RTYPE (tree)))
2017 werror (E_IDX_NOT_INT);
2018 goto errorTreeReturn;
2021 /* if the left is an rvalue then error */
2024 werror (E_LVALUE_REQUIRED, "array access");
2025 goto errorTreeReturn;
2028 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2029 if (IS_PTR(LTYPE(tree))) {
2030 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2034 /*------------------------------------------------------------------*/
2035 /*----------------------------*/
2037 /*----------------------------*/
2039 /* if this is not a structure */
2040 if (!IS_STRUCT (LTYPE (tree)))
2042 werror (E_STRUCT_UNION, ".");
2043 goto errorTreeReturn;
2045 TTYPE (tree) = structElemType (LTYPE (tree),
2046 (tree->right->type == EX_VALUE ?
2047 tree->right->opval.val : NULL), &tree->args);
2048 TETYPE (tree) = getSpec (TTYPE (tree));
2051 /*------------------------------------------------------------------*/
2052 /*----------------------------*/
2053 /* struct/union pointer */
2054 /*----------------------------*/
2056 /* if not pointer to a structure */
2057 if (!IS_PTR (LTYPE (tree)))
2059 werror (E_PTR_REQD);
2060 goto errorTreeReturn;
2063 if (!IS_STRUCT (LTYPE (tree)->next))
2065 werror (E_STRUCT_UNION, "->");
2066 goto errorTreeReturn;
2069 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2070 (tree->right->type == EX_VALUE ?
2071 tree->right->opval.val : NULL), &tree->args);
2072 TETYPE (tree) = getSpec (TTYPE (tree));
2075 /*------------------------------------------------------------------*/
2076 /*----------------------------*/
2077 /* ++/-- operation */
2078 /*----------------------------*/
2079 case INC_OP: /* incerement operator unary so left only */
2082 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2083 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2084 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2085 werror (E_CODE_WRITE, "++/--");
2094 /*------------------------------------------------------------------*/
2095 /*----------------------------*/
2097 /*----------------------------*/
2098 case '&': /* can be unary */
2099 /* if right is NULL then unary operation */
2100 if (tree->right) /* not an unary operation */
2103 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2105 werror (E_BITWISE_OP);
2106 werror (W_CONTINUE, "left & right types are ");
2107 printTypeChain (LTYPE (tree), stderr);
2108 fprintf (stderr, ",");
2109 printTypeChain (RTYPE (tree), stderr);
2110 fprintf (stderr, "\n");
2111 goto errorTreeReturn;
2114 /* if they are both literal */
2115 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2117 tree->type = EX_VALUE;
2118 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2119 valFromType (RETYPE (tree)), '&');
2121 tree->right = tree->left = NULL;
2122 TETYPE (tree) = tree->opval.val->etype;
2123 TTYPE (tree) = tree->opval.val->type;
2127 /* see if this is a GETHBIT operation if yes
2130 ast *otree = optimizeGetHbit (tree);
2133 return decorateType (otree);
2137 // we can't do this because of "(int & 0xff) << 3"
2139 /* if right or left is literal then result of that type */
2140 if (IS_LITERAL (RTYPE (tree)))
2143 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2144 TETYPE (tree) = getSpec (TTYPE (tree));
2145 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2149 if (IS_LITERAL (LTYPE (tree)))
2151 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2152 TETYPE (tree) = getSpec (TTYPE (tree));
2153 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2159 computeType (LTYPE (tree), RTYPE (tree));
2160 TETYPE (tree) = getSpec (TTYPE (tree));
2165 computeType (LTYPE (tree), RTYPE (tree));
2166 TETYPE (tree) = getSpec (TTYPE (tree));
2168 LRVAL (tree) = RRVAL (tree) = 1;
2172 /*------------------------------------------------------------------*/
2173 /*----------------------------*/
2175 /*----------------------------*/
2177 p->class = DECLARATOR;
2178 /* if bit field then error */
2179 if (IS_BITVAR (tree->left->etype))
2181 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2182 goto errorTreeReturn;
2185 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2187 werror (E_ILLEGAL_ADDR, "address of register variable");
2188 goto errorTreeReturn;
2191 if (IS_FUNC (LTYPE (tree)))
2193 werror (E_ILLEGAL_ADDR, "address of function");
2194 goto errorTreeReturn;
2199 werror (E_LVALUE_REQUIRED, "address of");
2200 goto errorTreeReturn;
2202 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2204 DCL_TYPE (p) = CPOINTER;
2205 DCL_PTR_CONST (p) = port->mem.code_ro;
2207 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2208 DCL_TYPE (p) = FPOINTER;
2209 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2210 DCL_TYPE (p) = PPOINTER;
2211 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2212 DCL_TYPE (p) = IPOINTER;
2213 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2214 DCL_TYPE (p) = EEPPOINTER;
2216 DCL_TYPE (p) = POINTER;
2218 if (IS_AST_SYM_VALUE (tree->left))
2220 AST_SYMBOL (tree->left)->addrtaken = 1;
2221 AST_SYMBOL (tree->left)->allocreq = 1;
2224 p->next = LTYPE (tree);
2226 TETYPE (tree) = getSpec (TTYPE (tree));
2227 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2228 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2233 /*------------------------------------------------------------------*/
2234 /*----------------------------*/
2236 /*----------------------------*/
2238 /* if the rewrite succeeds then don't go any furthur */
2240 ast *wtree = optimizeRRCRLC (tree);
2242 return decorateType (wtree);
2244 /*------------------------------------------------------------------*/
2245 /*----------------------------*/
2247 /*----------------------------*/
2249 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2251 werror (E_BITWISE_OP);
2252 werror (W_CONTINUE, "left & right types are ");
2253 printTypeChain (LTYPE (tree), stderr);
2254 fprintf (stderr, ",");
2255 printTypeChain (RTYPE (tree), stderr);
2256 fprintf (stderr, "\n");
2257 goto errorTreeReturn;
2260 /* if they are both literal then */
2261 /* rewrite the tree */
2262 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2264 tree->type = EX_VALUE;
2265 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2266 valFromType (RETYPE (tree)),
2268 tree->right = tree->left = NULL;
2269 TETYPE (tree) = tree->opval.val->etype;
2270 TTYPE (tree) = tree->opval.val->type;
2273 LRVAL (tree) = RRVAL (tree) = 1;
2274 TETYPE (tree) = getSpec (TTYPE (tree) =
2275 computeType (LTYPE (tree),
2278 /*------------------------------------------------------------------*/
2279 /*----------------------------*/
2281 /*----------------------------*/
2283 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2285 werror (E_INVALID_OP, "divide");
2286 goto errorTreeReturn;
2288 /* if they are both literal then */
2289 /* rewrite the tree */
2290 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2292 tree->type = EX_VALUE;
2293 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2294 valFromType (RETYPE (tree)));
2295 tree->right = tree->left = NULL;
2296 TETYPE (tree) = getSpec (TTYPE (tree) =
2297 tree->opval.val->type);
2300 LRVAL (tree) = RRVAL (tree) = 1;
2301 TETYPE (tree) = getSpec (TTYPE (tree) =
2302 computeType (LTYPE (tree),
2306 /*------------------------------------------------------------------*/
2307 /*----------------------------*/
2309 /*----------------------------*/
2311 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2313 werror (E_BITWISE_OP);
2314 werror (W_CONTINUE, "left & right types are ");
2315 printTypeChain (LTYPE (tree), stderr);
2316 fprintf (stderr, ",");
2317 printTypeChain (RTYPE (tree), stderr);
2318 fprintf (stderr, "\n");
2319 goto errorTreeReturn;
2321 /* if they are both literal then */
2322 /* rewrite the tree */
2323 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2325 tree->type = EX_VALUE;
2326 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2327 valFromType (RETYPE (tree)));
2328 tree->right = tree->left = NULL;
2329 TETYPE (tree) = getSpec (TTYPE (tree) =
2330 tree->opval.val->type);
2333 LRVAL (tree) = RRVAL (tree) = 1;
2334 TETYPE (tree) = getSpec (TTYPE (tree) =
2335 computeType (LTYPE (tree),
2339 /*------------------------------------------------------------------*/
2340 /*----------------------------*/
2341 /* address dereference */
2342 /*----------------------------*/
2343 case '*': /* can be unary : if right is null then unary operation */
2346 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2348 werror (E_PTR_REQD);
2349 goto errorTreeReturn;
2354 werror (E_LVALUE_REQUIRED, "pointer deref");
2355 goto errorTreeReturn;
2357 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2358 LTYPE (tree)->next : NULL);
2359 TETYPE (tree) = getSpec (TTYPE (tree));
2360 tree->args = tree->left->args;
2361 tree->hasVargs = tree->left->hasVargs;
2362 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2366 /*------------------------------------------------------------------*/
2367 /*----------------------------*/
2368 /* multiplication */
2369 /*----------------------------*/
2370 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2372 werror (E_INVALID_OP, "multiplication");
2373 goto errorTreeReturn;
2376 /* if they are both literal then */
2377 /* rewrite the tree */
2378 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2380 tree->type = EX_VALUE;
2381 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2382 valFromType (RETYPE (tree)));
2383 tree->right = tree->left = NULL;
2384 TETYPE (tree) = getSpec (TTYPE (tree) =
2385 tree->opval.val->type);
2389 /* if left is a literal exchange left & right */
2390 if (IS_LITERAL (LTYPE (tree)))
2392 ast *tTree = tree->left;
2393 tree->left = tree->right;
2394 tree->right = tTree;
2397 LRVAL (tree) = RRVAL (tree) = 1;
2398 /* promote result to int if left & right are char
2399 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2400 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2401 TETYPE (tree) = getSpec (TTYPE (tree) =
2402 computeType (LTYPE (tree),
2404 SPEC_NOUN(TETYPE(tree)) = V_INT;
2406 TETYPE (tree) = getSpec (TTYPE (tree) =
2407 computeType (LTYPE (tree),
2412 /*------------------------------------------------------------------*/
2413 /*----------------------------*/
2414 /* unary '+' operator */
2415 /*----------------------------*/
2420 if (!IS_INTEGRAL (LTYPE (tree)))
2422 werror (E_UNARY_OP, '+');
2423 goto errorTreeReturn;
2426 /* if left is a literal then do it */
2427 if (IS_LITERAL (LTYPE (tree)))
2429 tree->type = EX_VALUE;
2430 tree->opval.val = valFromType (LETYPE (tree));
2432 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2436 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2440 /*------------------------------------------------------------------*/
2441 /*----------------------------*/
2443 /*----------------------------*/
2445 /* this is not a unary operation */
2446 /* if both pointers then problem */
2447 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2448 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2450 werror (E_PTR_PLUS_PTR);
2451 goto errorTreeReturn;
2454 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2455 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2457 werror (E_PLUS_INVALID, "+");
2458 goto errorTreeReturn;
2461 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2462 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2464 werror (E_PLUS_INVALID, "+");
2465 goto errorTreeReturn;
2467 /* if they are both literal then */
2468 /* rewrite the tree */
2469 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2471 tree->type = EX_VALUE;
2472 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2473 valFromType (RETYPE (tree)));
2474 tree->right = tree->left = NULL;
2475 TETYPE (tree) = getSpec (TTYPE (tree) =
2476 tree->opval.val->type);
2480 /* if the right is a pointer or left is a literal
2481 xchange left & right */
2482 if (IS_ARRAY (RTYPE (tree)) ||
2483 IS_PTR (RTYPE (tree)) ||
2484 IS_LITERAL (LTYPE (tree)))
2486 ast *tTree = tree->left;
2487 tree->left = tree->right;
2488 tree->right = tTree;
2491 LRVAL (tree) = RRVAL (tree) = 1;
2492 /* if the left is a pointer */
2493 if (IS_PTR (LTYPE (tree)))
2494 TETYPE (tree) = getSpec (TTYPE (tree) =
2497 TETYPE (tree) = getSpec (TTYPE (tree) =
2498 computeType (LTYPE (tree),
2502 /*------------------------------------------------------------------*/
2503 /*----------------------------*/
2505 /*----------------------------*/
2506 case '-': /* can be unary */
2507 /* if right is null then unary */
2511 if (!IS_ARITHMETIC (LTYPE (tree)))
2513 werror (E_UNARY_OP, tree->opval.op);
2514 goto errorTreeReturn;
2517 /* if left is a literal then do it */
2518 if (IS_LITERAL (LTYPE (tree)))
2520 tree->type = EX_VALUE;
2521 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2523 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2524 SPEC_USIGN(TETYPE(tree)) = 0;
2528 TTYPE (tree) = LTYPE (tree);
2532 /*------------------------------------------------------------------*/
2533 /*----------------------------*/
2535 /*----------------------------*/
2537 if (!(IS_PTR (LTYPE (tree)) ||
2538 IS_ARRAY (LTYPE (tree)) ||
2539 IS_ARITHMETIC (LTYPE (tree))))
2541 werror (E_PLUS_INVALID, "-");
2542 goto errorTreeReturn;
2545 if (!(IS_PTR (RTYPE (tree)) ||
2546 IS_ARRAY (RTYPE (tree)) ||
2547 IS_ARITHMETIC (RTYPE (tree))))
2549 werror (E_PLUS_INVALID, "-");
2550 goto errorTreeReturn;
2553 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2554 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2555 IS_INTEGRAL (RTYPE (tree))))
2557 werror (E_PLUS_INVALID, "-");
2558 goto errorTreeReturn;
2561 /* if they are both literal then */
2562 /* rewrite the tree */
2563 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2565 tree->type = EX_VALUE;
2566 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2567 valFromType (RETYPE (tree)));
2568 tree->right = tree->left = NULL;
2569 TETYPE (tree) = getSpec (TTYPE (tree) =
2570 tree->opval.val->type);
2574 /* if the left & right are equal then zero */
2575 if (isAstEqual (tree->left, tree->right))
2577 tree->type = EX_VALUE;
2578 tree->left = tree->right = NULL;
2579 tree->opval.val = constVal ("0");
2580 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2584 /* if both of them are pointers or arrays then */
2585 /* the result is going to be an integer */
2586 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2587 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2588 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2590 /* if only the left is a pointer */
2591 /* then result is a pointer */
2592 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2593 TETYPE (tree) = getSpec (TTYPE (tree) =
2596 TETYPE (tree) = getSpec (TTYPE (tree) =
2597 computeType (LTYPE (tree),
2599 LRVAL (tree) = RRVAL (tree) = 1;
2602 /*------------------------------------------------------------------*/
2603 /*----------------------------*/
2605 /*----------------------------*/
2607 /* can be only integral type */
2608 if (!IS_INTEGRAL (LTYPE (tree)))
2610 werror (E_UNARY_OP, tree->opval.op);
2611 goto errorTreeReturn;
2614 /* if left is a literal then do it */
2615 if (IS_LITERAL (LTYPE (tree)))
2617 tree->type = EX_VALUE;
2618 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2620 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2624 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2627 /*------------------------------------------------------------------*/
2628 /*----------------------------*/
2630 /*----------------------------*/
2632 /* can be pointer */
2633 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2634 !IS_PTR (LTYPE (tree)) &&
2635 !IS_ARRAY (LTYPE (tree)))
2637 werror (E_UNARY_OP, tree->opval.op);
2638 goto errorTreeReturn;
2641 /* if left is a literal then do it */
2642 if (IS_LITERAL (LTYPE (tree)))
2644 tree->type = EX_VALUE;
2645 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2647 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2651 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2654 /*------------------------------------------------------------------*/
2655 /*----------------------------*/
2657 /*----------------------------*/
2660 TTYPE (tree) = LTYPE (tree);
2661 TETYPE (tree) = LETYPE (tree);
2665 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2670 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2672 werror (E_SHIFT_OP_INVALID);
2673 werror (W_CONTINUE, "left & right types are ");
2674 printTypeChain (LTYPE (tree), stderr);
2675 fprintf (stderr, ",");
2676 printTypeChain (RTYPE (tree), stderr);
2677 fprintf (stderr, "\n");
2678 goto errorTreeReturn;
2681 /* if they are both literal then */
2682 /* rewrite the tree */
2683 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2685 tree->type = EX_VALUE;
2686 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2687 valFromType (RETYPE (tree)),
2688 (tree->opval.op == LEFT_OP ? 1 : 0));
2689 tree->right = tree->left = NULL;
2690 TETYPE (tree) = getSpec (TTYPE (tree) =
2691 tree->opval.val->type);
2694 /* if only the right side is a literal & we are
2695 shifting more than size of the left operand then zero */
2696 if (IS_LITERAL (RTYPE (tree)) &&
2697 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2698 (getSize (LTYPE (tree)) * 8))
2700 werror (W_SHIFT_CHANGED,
2701 (tree->opval.op == LEFT_OP ? "left" : "right"));
2702 tree->type = EX_VALUE;
2703 tree->left = tree->right = NULL;
2704 tree->opval.val = constVal ("0");
2705 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2708 LRVAL (tree) = RRVAL (tree) = 1;
2709 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2711 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2715 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2719 /*------------------------------------------------------------------*/
2720 /*----------------------------*/
2722 /*----------------------------*/
2723 case CAST: /* change the type */
2724 /* cannot cast to an aggregate type */
2725 if (IS_AGGREGATE (LTYPE (tree)))
2727 werror (E_CAST_ILLEGAL);
2728 goto errorTreeReturn;
2731 /* make sure the type is complete and sane */
2732 checkTypeSanity(LETYPE(tree), "(cast)");
2735 /* if the right is a literal replace the tree */
2736 if (IS_LITERAL (RETYPE (tree))) {
2737 if (!IS_PTR (LTYPE (tree))) {
2738 tree->type = EX_VALUE;
2740 valCastLiteral (LTYPE (tree),
2741 floatFromVal (valFromType (RETYPE (tree))));
2744 TTYPE (tree) = tree->opval.val->type;
2745 tree->values.literalFromCast = 1;
2746 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2747 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2748 sym_link *rest = LTYPE(tree)->next;
2749 werror(W_LITERAL_GENERIC);
2750 TTYPE(tree) = newLink();
2751 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2752 TTYPE(tree)->next = rest;
2753 tree->left->opval.lnk = TTYPE(tree);
2756 TTYPE (tree) = LTYPE (tree);
2760 TTYPE (tree) = LTYPE (tree);
2764 /* if the right is a literal replace the tree */
2765 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2766 tree->type = EX_VALUE;
2768 valCastLiteral (LTYPE (tree),
2769 floatFromVal (valFromType (RETYPE (tree))));
2772 TTYPE (tree) = tree->opval.val->type;
2773 tree->values.literalFromCast = 1;
2775 TTYPE (tree) = LTYPE (tree);
2780 TETYPE (tree) = getSpec (TTYPE (tree));
2784 /*------------------------------------------------------------------*/
2785 /*----------------------------*/
2786 /* logical &&, || */
2787 /*----------------------------*/
2790 /* each must me arithmetic type or be a pointer */
2791 if (!IS_PTR (LTYPE (tree)) &&
2792 !IS_ARRAY (LTYPE (tree)) &&
2793 !IS_INTEGRAL (LTYPE (tree)))
2795 werror (E_COMPARE_OP);
2796 goto errorTreeReturn;
2799 if (!IS_PTR (RTYPE (tree)) &&
2800 !IS_ARRAY (RTYPE (tree)) &&
2801 !IS_INTEGRAL (RTYPE (tree)))
2803 werror (E_COMPARE_OP);
2804 goto errorTreeReturn;
2806 /* if they are both literal then */
2807 /* rewrite the tree */
2808 if (IS_LITERAL (RTYPE (tree)) &&
2809 IS_LITERAL (LTYPE (tree)))
2811 tree->type = EX_VALUE;
2812 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2813 valFromType (RETYPE (tree)),
2815 tree->right = tree->left = NULL;
2816 TETYPE (tree) = getSpec (TTYPE (tree) =
2817 tree->opval.val->type);
2820 LRVAL (tree) = RRVAL (tree) = 1;
2821 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2824 /*------------------------------------------------------------------*/
2825 /*----------------------------*/
2826 /* comparison operators */
2827 /*----------------------------*/
2835 ast *lt = optimizeCompare (tree);
2841 /* if they are pointers they must be castable */
2842 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2844 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2846 werror (E_COMPARE_OP);
2847 fprintf (stderr, "comparing type ");
2848 printTypeChain (LTYPE (tree), stderr);
2849 fprintf (stderr, "to type ");
2850 printTypeChain (RTYPE (tree), stderr);
2851 fprintf (stderr, "\n");
2852 goto errorTreeReturn;
2855 /* else they should be promotable to one another */
2858 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2859 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2861 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2863 werror (E_COMPARE_OP);
2864 fprintf (stderr, "comparing type ");
2865 printTypeChain (LTYPE (tree), stderr);
2866 fprintf (stderr, "to type ");
2867 printTypeChain (RTYPE (tree), stderr);
2868 fprintf (stderr, "\n");
2869 goto errorTreeReturn;
2873 /* if they are both literal then */
2874 /* rewrite the tree */
2875 if (IS_LITERAL (RTYPE (tree)) &&
2876 IS_LITERAL (LTYPE (tree)))
2878 tree->type = EX_VALUE;
2879 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2880 valFromType (RETYPE (tree)),
2882 tree->right = tree->left = NULL;
2883 TETYPE (tree) = getSpec (TTYPE (tree) =
2884 tree->opval.val->type);
2887 LRVAL (tree) = RRVAL (tree) = 1;
2888 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2891 /*------------------------------------------------------------------*/
2892 /*----------------------------*/
2894 /*----------------------------*/
2895 case SIZEOF: /* evaluate wihout code generation */
2896 /* change the type to a integer */
2897 tree->type = EX_VALUE;
2898 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2899 tree->opval.val = constVal (buffer);
2900 tree->right = tree->left = NULL;
2901 TETYPE (tree) = getSpec (TTYPE (tree) =
2902 tree->opval.val->type);
2905 /*------------------------------------------------------------------*/
2906 /*----------------------------*/
2907 /* conditional operator '?' */
2908 /*----------------------------*/
2910 /* the type is value of the colon operator (on the right) */
2911 assert(IS_COLON_OP(tree->right));
2912 /* if already known then replace the tree : optimizer will do it
2913 but faster to do it here */
2914 if (IS_LITERAL (LTYPE(tree))) {
2915 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2916 return tree->right->left ;
2918 return tree->right->right ;
2921 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2922 TETYPE (tree) = getSpec (TTYPE (tree));
2927 /* if they don't match we have a problem */
2928 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2930 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2931 goto errorTreeReturn;
2934 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2935 TETYPE (tree) = getSpec (TTYPE (tree));
2939 /*------------------------------------------------------------------*/
2940 /*----------------------------*/
2941 /* assignment operators */
2942 /*----------------------------*/
2945 /* for these it must be both must be integral */
2946 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2947 !IS_ARITHMETIC (RTYPE (tree)))
2949 werror (E_OPS_INTEGRAL);
2950 goto errorTreeReturn;
2953 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2955 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2956 werror (E_CODE_WRITE, " ");
2960 werror (E_LVALUE_REQUIRED, "*= or /=");
2961 goto errorTreeReturn;
2974 /* for these it must be both must be integral */
2975 if (!IS_INTEGRAL (LTYPE (tree)) ||
2976 !IS_INTEGRAL (RTYPE (tree)))
2978 werror (E_OPS_INTEGRAL);
2979 goto errorTreeReturn;
2982 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2984 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2985 werror (E_CODE_WRITE, " ");
2989 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2990 goto errorTreeReturn;
2998 /*------------------------------------------------------------------*/
2999 /*----------------------------*/
3001 /*----------------------------*/
3003 if (!(IS_PTR (LTYPE (tree)) ||
3004 IS_ARITHMETIC (LTYPE (tree))))
3006 werror (E_PLUS_INVALID, "-=");
3007 goto errorTreeReturn;
3010 if (!(IS_PTR (RTYPE (tree)) ||
3011 IS_ARITHMETIC (RTYPE (tree))))
3013 werror (E_PLUS_INVALID, "-=");
3014 goto errorTreeReturn;
3017 TETYPE (tree) = getSpec (TTYPE (tree) =
3018 computeType (LTYPE (tree),
3021 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3022 werror (E_CODE_WRITE, " ");
3026 werror (E_LVALUE_REQUIRED, "-=");
3027 goto errorTreeReturn;
3035 /*------------------------------------------------------------------*/
3036 /*----------------------------*/
3038 /*----------------------------*/
3040 /* this is not a unary operation */
3041 /* if both pointers then problem */
3042 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3044 werror (E_PTR_PLUS_PTR);
3045 goto errorTreeReturn;
3048 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3050 werror (E_PLUS_INVALID, "+=");
3051 goto errorTreeReturn;
3054 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3056 werror (E_PLUS_INVALID, "+=");
3057 goto errorTreeReturn;
3060 TETYPE (tree) = getSpec (TTYPE (tree) =
3061 computeType (LTYPE (tree),
3064 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3065 werror (E_CODE_WRITE, " ");
3069 werror (E_LVALUE_REQUIRED, "+=");
3070 goto errorTreeReturn;
3073 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3074 tree->opval.op = '=';
3080 /*------------------------------------------------------------------*/
3081 /*----------------------------*/
3082 /* straight assignemnt */
3083 /*----------------------------*/
3085 /* cannot be an aggregate */
3086 if (IS_AGGREGATE (LTYPE (tree)))
3088 werror (E_AGGR_ASSIGN);
3089 goto errorTreeReturn;
3092 /* they should either match or be castable */
3093 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3095 werror (E_TYPE_MISMATCH, "assignment", " ");
3096 fprintf (stderr, "type --> '");
3097 printTypeChain (RTYPE (tree), stderr);
3098 fprintf (stderr, "' ");
3099 fprintf (stderr, "assigned to type --> '");
3100 printTypeChain (LTYPE (tree), stderr);
3101 fprintf (stderr, "'\n");
3102 goto errorTreeReturn;
3105 /* if the left side of the tree is of type void
3106 then report error */
3107 if (IS_VOID (LTYPE (tree)))
3109 werror (E_CAST_ZERO);
3110 fprintf (stderr, "type --> '");
3111 printTypeChain (RTYPE (tree), stderr);
3112 fprintf (stderr, "' ");
3113 fprintf (stderr, "assigned to type --> '");
3114 printTypeChain (LTYPE (tree), stderr);
3115 fprintf (stderr, "'\n");
3118 TETYPE (tree) = getSpec (TTYPE (tree) =
3122 if (!tree->initMode ) {
3123 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3124 werror (E_CODE_WRITE, " ");
3128 werror (E_LVALUE_REQUIRED, "=");
3129 goto errorTreeReturn;
3136 /*------------------------------------------------------------------*/
3137 /*----------------------------*/
3138 /* comma operator */
3139 /*----------------------------*/
3141 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3144 /*------------------------------------------------------------------*/
3145 /*----------------------------*/
3147 /*----------------------------*/
3151 if (processParms (tree->left,
3153 tree->right, &parmNumber, TRUE))
3154 goto errorTreeReturn;
3156 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3158 tree->left->args = reverseVal (tree->left->args);
3159 reverseParms (tree->right);
3162 tree->args = tree->left->args;
3163 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3166 /*------------------------------------------------------------------*/
3167 /*----------------------------*/
3168 /* return statement */
3169 /*----------------------------*/
3174 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3176 werror (W_RETURN_MISMATCH);
3177 fprintf (stderr, "from type '");
3178 printTypeChain (RTYPE(tree), stderr);
3179 fprintf (stderr, "' to type '");
3180 printTypeChain (currFunc->type->next, stderr);
3181 fprintf (stderr, "'\n");
3182 goto errorTreeReturn;
3185 if (IS_VOID (currFunc->type->next)
3187 !IS_VOID (RTYPE (tree)))
3189 werror (E_FUNC_VOID);
3190 goto errorTreeReturn;
3193 /* if there is going to be a casing required then add it */
3194 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3196 #if 0 && defined DEMAND_INTEGER_PROMOTION
3197 if (IS_INTEGRAL (currFunc->type->next))
3199 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3205 decorateType (newNode (CAST,
3206 newAst_LINK (copyLinkChain (currFunc->type->next)),
3216 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3218 werror (E_VOID_FUNC, currFunc->name);
3219 goto errorTreeReturn;
3222 TTYPE (tree) = TETYPE (tree) = NULL;
3225 /*------------------------------------------------------------------*/
3226 /*----------------------------*/
3227 /* switch statement */
3228 /*----------------------------*/
3230 /* the switch value must be an integer */
3231 if (!IS_INTEGRAL (LTYPE (tree)))
3233 werror (E_SWITCH_NON_INTEGER);
3234 goto errorTreeReturn;
3237 TTYPE (tree) = TETYPE (tree) = NULL;
3240 /*------------------------------------------------------------------*/
3241 /*----------------------------*/
3243 /*----------------------------*/
3245 tree->left = backPatchLabels (tree->left,
3248 TTYPE (tree) = TETYPE (tree) = NULL;
3251 /*------------------------------------------------------------------*/
3252 /*----------------------------*/
3254 /*----------------------------*/
3257 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3258 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3259 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3261 /* if the for loop is reversible then
3262 reverse it otherwise do what we normally
3268 if (isLoopReversible (tree, &sym, &init, &end))
3269 return reverseLoop (tree, sym, init, end);
3271 return decorateType (createFor (AST_FOR (tree, trueLabel),
3272 AST_FOR (tree, continueLabel),
3273 AST_FOR (tree, falseLabel),
3274 AST_FOR (tree, condLabel),
3275 AST_FOR (tree, initExpr),
3276 AST_FOR (tree, condExpr),
3277 AST_FOR (tree, loopExpr),
3281 TTYPE (tree) = TETYPE (tree) = NULL;
3285 /* some error found this tree will be killed */
3287 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3288 tree->opval.op = NULLOP;
3294 /*-----------------------------------------------------------------*/
3295 /* sizeofOp - processes size of operation */
3296 /*-----------------------------------------------------------------*/
3298 sizeofOp (sym_link * type)
3302 /* make sure the type is complete and sane */
3303 checkTypeSanity(type, "(sizeof)");
3305 /* get the size and convert it to character */
3306 sprintf (buff, "%d", getSize (type));
3308 /* now convert into value */
3309 return constVal (buff);
3313 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3314 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3315 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3316 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3317 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3318 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3319 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3321 /*-----------------------------------------------------------------*/
3322 /* backPatchLabels - change and or not operators to flow control */
3323 /*-----------------------------------------------------------------*/
3325 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3331 if (!(IS_ANDORNOT (tree)))
3334 /* if this an and */
3337 static int localLbl = 0;
3340 sprintf (buffer, "_and_%d", localLbl++);
3341 localLabel = newSymbol (buffer, NestLevel);
3343 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3345 /* if left is already a IFX then just change the if true label in that */
3346 if (!IS_IFX (tree->left))
3347 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3349 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3350 /* right is a IFX then just join */
3351 if (IS_IFX (tree->right))
3352 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3354 tree->right = createLabel (localLabel, tree->right);
3355 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3357 return newNode (NULLOP, tree->left, tree->right);
3360 /* if this is an or operation */
3363 static int localLbl = 0;
3366 sprintf (buffer, "_or_%d", localLbl++);
3367 localLabel = newSymbol (buffer, NestLevel);
3369 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3371 /* if left is already a IFX then just change the if true label in that */
3372 if (!IS_IFX (tree->left))
3373 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3375 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3376 /* right is a IFX then just join */
3377 if (IS_IFX (tree->right))
3378 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3380 tree->right = createLabel (localLabel, tree->right);
3381 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3383 return newNode (NULLOP, tree->left, tree->right);
3389 int wasnot = IS_NOT (tree->left);
3390 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3392 /* if the left is already a IFX */
3393 if (!IS_IFX (tree->left))
3394 tree->left = newNode (IFX, tree->left, NULL);
3398 tree->left->trueLabel = trueLabel;
3399 tree->left->falseLabel = falseLabel;
3403 tree->left->trueLabel = falseLabel;
3404 tree->left->falseLabel = trueLabel;
3411 tree->trueLabel = trueLabel;
3412 tree->falseLabel = falseLabel;
3419 /*-----------------------------------------------------------------*/
3420 /* createBlock - create expression tree for block */
3421 /*-----------------------------------------------------------------*/
3423 createBlock (symbol * decl, ast * body)
3427 /* if the block has nothing */
3431 ex = newNode (BLOCK, NULL, body);
3432 ex->values.sym = decl;
3434 ex->right = ex->right;
3440 /*-----------------------------------------------------------------*/
3441 /* createLabel - creates the expression tree for labels */
3442 /*-----------------------------------------------------------------*/
3444 createLabel (symbol * label, ast * stmnt)
3447 char name[SDCC_NAME_MAX + 1];
3450 /* must create fresh symbol if the symbol name */
3451 /* exists in the symbol table, since there can */
3452 /* be a variable with the same name as the labl */
3453 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3454 (csym->level == label->level))
3455 label = newSymbol (label->name, label->level);
3457 /* change the name before putting it in add _ */
3458 sprintf (name, "%s", label->name);
3460 /* put the label in the LabelSymbol table */
3461 /* but first check if a label of the same */
3463 if ((csym = findSym (LabelTab, NULL, name)))
3464 werror (E_DUPLICATE_LABEL, label->name);
3466 addSym (LabelTab, label, name, label->level, 0, 0);
3469 label->key = labelKey++;
3470 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3476 /*-----------------------------------------------------------------*/
3477 /* createCase - generates the parsetree for a case statement */
3478 /*-----------------------------------------------------------------*/
3480 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3482 char caseLbl[SDCC_NAME_MAX + 1];
3486 /* if the switch statement does not exist */
3487 /* then case is out of context */
3490 werror (E_CASE_CONTEXT);
3494 caseVal = decorateType (resolveSymbols (caseVal));
3495 /* if not a constant then error */
3496 if (!IS_LITERAL (caseVal->ftype))
3498 werror (E_CASE_CONSTANT);
3502 /* if not a integer than error */
3503 if (!IS_INTEGRAL (caseVal->ftype))
3505 werror (E_CASE_NON_INTEGER);
3509 /* find the end of the switch values chain */
3510 if (!(val = swStat->values.switchVals.swVals))
3511 swStat->values.switchVals.swVals = caseVal->opval.val;
3514 /* also order the cases according to value */
3516 int cVal = (int) floatFromVal (caseVal->opval.val);
3517 while (val && (int) floatFromVal (val) < cVal)
3523 /* if we reached the end then */
3526 pval->next = caseVal->opval.val;
3530 /* we found a value greater than */
3531 /* the current value we must add this */
3532 /* before the value */
3533 caseVal->opval.val->next = val;
3535 /* if this was the first in chain */
3536 if (swStat->values.switchVals.swVals == val)
3537 swStat->values.switchVals.swVals =
3540 pval->next = caseVal->opval.val;
3545 /* create the case label */
3546 sprintf (caseLbl, "_case_%d_%d",
3547 swStat->values.switchVals.swNum,
3548 (int) floatFromVal (caseVal->opval.val));
3550 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3555 /*-----------------------------------------------------------------*/
3556 /* createDefault - creates the parse tree for the default statement */
3557 /*-----------------------------------------------------------------*/
3559 createDefault (ast * swStat, ast * stmnt)
3561 char defLbl[SDCC_NAME_MAX + 1];
3563 /* if the switch statement does not exist */
3564 /* then case is out of context */
3567 werror (E_CASE_CONTEXT);
3571 /* turn on the default flag */
3572 swStat->values.switchVals.swDefault = 1;
3574 /* create the label */
3575 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3576 return createLabel (newSymbol (defLbl, 0), stmnt);
3579 /*-----------------------------------------------------------------*/
3580 /* createIf - creates the parsetree for the if statement */
3581 /*-----------------------------------------------------------------*/
3583 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3585 static int Lblnum = 0;
3587 symbol *ifTrue, *ifFalse, *ifEnd;
3589 /* if neither exists */
3590 if (!elseBody && !ifBody)
3593 /* create the labels */
3594 sprintf (buffer, "_iffalse_%d", Lblnum);
3595 ifFalse = newSymbol (buffer, NestLevel);
3596 /* if no else body then end == false */
3601 sprintf (buffer, "_ifend_%d", Lblnum);
3602 ifEnd = newSymbol (buffer, NestLevel);
3605 sprintf (buffer, "_iftrue_%d", Lblnum);
3606 ifTrue = newSymbol (buffer, NestLevel);
3610 /* attach the ifTrue label to the top of it body */
3611 ifBody = createLabel (ifTrue, ifBody);
3612 /* attach a goto end to the ifBody if else is present */
3615 ifBody = newNode (NULLOP, ifBody,
3617 newAst_VALUE (symbolVal (ifEnd)),
3619 /* put the elseLabel on the else body */
3620 elseBody = createLabel (ifFalse, elseBody);
3621 /* out the end at the end of the body */
3622 elseBody = newNode (NULLOP,
3624 createLabel (ifEnd, NULL));
3628 ifBody = newNode (NULLOP, ifBody,
3629 createLabel (ifFalse, NULL));
3631 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3632 if (IS_IFX (condAst))
3635 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3637 return newNode (NULLOP, ifTree,
3638 newNode (NULLOP, ifBody, elseBody));
3642 /*-----------------------------------------------------------------*/
3643 /* createDo - creates parse tree for do */
3646 /* _docontinue_n: */
3647 /* condition_expression +-> trueLabel -> _dobody_n */
3649 /* +-> falseLabel-> _dobreak_n */
3651 /*-----------------------------------------------------------------*/
3653 createDo (symbol * trueLabel, symbol * continueLabel,
3654 symbol * falseLabel, ast * condAst, ast * doBody)
3659 /* if the body does not exist then it is simple */
3662 condAst = backPatchLabels (condAst, continueLabel, NULL);
3663 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3664 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3665 doTree->trueLabel = continueLabel;
3666 doTree->falseLabel = NULL;
3670 /* otherwise we have a body */
3671 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3673 /* attach the body label to the top */
3674 doBody = createLabel (trueLabel, doBody);
3675 /* attach the continue label to end of body */
3676 doBody = newNode (NULLOP, doBody,
3677 createLabel (continueLabel, NULL));
3679 /* now put the break label at the end */
3680 if (IS_IFX (condAst))
3683 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3685 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3687 /* putting it together */
3688 return newNode (NULLOP, doBody, doTree);
3691 /*-----------------------------------------------------------------*/
3692 /* createFor - creates parse tree for 'for' statement */
3695 /* condExpr +-> trueLabel -> _forbody_n */
3697 /* +-> falseLabel-> _forbreak_n */
3700 /* _forcontinue_n: */
3702 /* goto _forcond_n ; */
3704 /*-----------------------------------------------------------------*/
3706 createFor (symbol * trueLabel, symbol * continueLabel,
3707 symbol * falseLabel, symbol * condLabel,
3708 ast * initExpr, ast * condExpr, ast * loopExpr,
3713 /* if loopexpression not present then we can generate it */
3714 /* the same way as a while */
3716 return newNode (NULLOP, initExpr,
3717 createWhile (trueLabel, continueLabel,
3718 falseLabel, condExpr, forBody));
3719 /* vanilla for statement */
3720 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3722 if (condExpr && !IS_IFX (condExpr))
3723 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3726 /* attach condition label to condition */
3727 condExpr = createLabel (condLabel, condExpr);
3729 /* attach body label to body */
3730 forBody = createLabel (trueLabel, forBody);
3732 /* attach continue to forLoop expression & attach */
3733 /* goto the forcond @ and of loopExpression */
3734 loopExpr = createLabel (continueLabel,
3738 newAst_VALUE (symbolVal (condLabel)),
3740 /* now start putting them together */
3741 forTree = newNode (NULLOP, initExpr, condExpr);
3742 forTree = newNode (NULLOP, forTree, forBody);
3743 forTree = newNode (NULLOP, forTree, loopExpr);
3744 /* finally add the break label */
3745 forTree = newNode (NULLOP, forTree,
3746 createLabel (falseLabel, NULL));
3750 /*-----------------------------------------------------------------*/
3751 /* createWhile - creates parse tree for while statement */
3752 /* the while statement will be created as follows */
3754 /* _while_continue_n: */
3755 /* condition_expression +-> trueLabel -> _while_boby_n */
3757 /* +-> falseLabel -> _while_break_n */
3758 /* _while_body_n: */
3760 /* goto _while_continue_n */
3761 /* _while_break_n: */
3762 /*-----------------------------------------------------------------*/
3764 createWhile (symbol * trueLabel, symbol * continueLabel,
3765 symbol * falseLabel, ast * condExpr, ast * whileBody)
3769 /* put the continue label */
3770 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3771 condExpr = createLabel (continueLabel, condExpr);
3772 condExpr->lineno = 0;
3774 /* put the body label in front of the body */
3775 whileBody = createLabel (trueLabel, whileBody);
3776 whileBody->lineno = 0;
3777 /* put a jump to continue at the end of the body */
3778 /* and put break label at the end of the body */
3779 whileBody = newNode (NULLOP,
3782 newAst_VALUE (symbolVal (continueLabel)),
3783 createLabel (falseLabel, NULL)));
3785 /* put it all together */
3786 if (IS_IFX (condExpr))
3787 whileTree = condExpr;
3790 whileTree = newNode (IFX, condExpr, NULL);
3791 /* put the true & false labels in place */
3792 whileTree->trueLabel = trueLabel;
3793 whileTree->falseLabel = falseLabel;
3796 return newNode (NULLOP, whileTree, whileBody);
3799 /*-----------------------------------------------------------------*/
3800 /* optimizeGetHbit - get highest order bit of the expression */
3801 /*-----------------------------------------------------------------*/
3803 optimizeGetHbit (ast * tree)
3806 /* if this is not a bit and */
3807 if (!IS_BITAND (tree))
3810 /* will look for tree of the form
3811 ( expr >> ((sizeof expr) -1) ) & 1 */
3812 if (!IS_AST_LIT_VALUE (tree->right))
3815 if (AST_LIT_VALUE (tree->right) != 1)
3818 if (!IS_RIGHT_OP (tree->left))
3821 if (!IS_AST_LIT_VALUE (tree->left->right))
3824 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3825 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3828 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3832 /*-----------------------------------------------------------------*/
3833 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3834 /*-----------------------------------------------------------------*/
3836 optimizeRRCRLC (ast * root)
3838 /* will look for trees of the form
3839 (?expr << 1) | (?expr >> 7) or
3840 (?expr >> 7) | (?expr << 1) will make that
3841 into a RLC : operation ..
3843 (?expr >> 1) | (?expr << 7) or
3844 (?expr << 7) | (?expr >> 1) will make that
3845 into a RRC operation
3846 note : by 7 I mean (number of bits required to hold the
3848 /* if the root operations is not a | operation the not */
3849 if (!IS_BITOR (root))
3852 /* I have to think of a better way to match patterns this sucks */
3853 /* that aside let start looking for the first case : I use a the
3854 negative check a lot to improve the efficiency */
3855 /* (?expr << 1) | (?expr >> 7) */
3856 if (IS_LEFT_OP (root->left) &&
3857 IS_RIGHT_OP (root->right))
3860 if (!SPEC_USIGN (TETYPE (root->left->left)))
3863 if (!IS_AST_LIT_VALUE (root->left->right) ||
3864 !IS_AST_LIT_VALUE (root->right->right))
3867 /* make sure it is the same expression */
3868 if (!isAstEqual (root->left->left,
3872 if (AST_LIT_VALUE (root->left->right) != 1)
3875 if (AST_LIT_VALUE (root->right->right) !=
3876 (getSize (TTYPE (root->left->left)) * 8 - 1))
3879 /* whew got the first case : create the AST */
3880 return newNode (RLC, root->left->left, NULL);
3884 /* check for second case */
3885 /* (?expr >> 7) | (?expr << 1) */
3886 if (IS_LEFT_OP (root->right) &&
3887 IS_RIGHT_OP (root->left))
3890 if (!SPEC_USIGN (TETYPE (root->left->left)))
3893 if (!IS_AST_LIT_VALUE (root->left->right) ||
3894 !IS_AST_LIT_VALUE (root->right->right))
3897 /* make sure it is the same symbol */
3898 if (!isAstEqual (root->left->left,
3902 if (AST_LIT_VALUE (root->right->right) != 1)
3905 if (AST_LIT_VALUE (root->left->right) !=
3906 (getSize (TTYPE (root->left->left)) * 8 - 1))
3909 /* whew got the first case : create the AST */
3910 return newNode (RLC, root->left->left, NULL);
3915 /* third case for RRC */
3916 /* (?symbol >> 1) | (?symbol << 7) */
3917 if (IS_LEFT_OP (root->right) &&
3918 IS_RIGHT_OP (root->left))
3921 if (!SPEC_USIGN (TETYPE (root->left->left)))
3924 if (!IS_AST_LIT_VALUE (root->left->right) ||
3925 !IS_AST_LIT_VALUE (root->right->right))
3928 /* make sure it is the same symbol */
3929 if (!isAstEqual (root->left->left,
3933 if (AST_LIT_VALUE (root->left->right) != 1)
3936 if (AST_LIT_VALUE (root->right->right) !=
3937 (getSize (TTYPE (root->left->left)) * 8 - 1))
3940 /* whew got the first case : create the AST */
3941 return newNode (RRC, root->left->left, NULL);
3945 /* fourth and last case for now */
3946 /* (?symbol << 7) | (?symbol >> 1) */
3947 if (IS_RIGHT_OP (root->right) &&
3948 IS_LEFT_OP (root->left))
3951 if (!SPEC_USIGN (TETYPE (root->left->left)))
3954 if (!IS_AST_LIT_VALUE (root->left->right) ||
3955 !IS_AST_LIT_VALUE (root->right->right))
3958 /* make sure it is the same symbol */
3959 if (!isAstEqual (root->left->left,
3963 if (AST_LIT_VALUE (root->right->right) != 1)
3966 if (AST_LIT_VALUE (root->left->right) !=
3967 (getSize (TTYPE (root->left->left)) * 8 - 1))
3970 /* whew got the first case : create the AST */
3971 return newNode (RRC, root->left->left, NULL);
3975 /* not found return root */
3979 /*-----------------------------------------------------------------*/
3980 /* optimizeCompare - otimizes compares for bit variables */
3981 /*-----------------------------------------------------------------*/
3983 optimizeCompare (ast * root)
3985 ast *optExpr = NULL;
3988 unsigned int litValue;
3990 /* if nothing then return nothing */
3994 /* if not a compare op then do leaves */
3995 if (!IS_COMPARE_OP (root))
3997 root->left = optimizeCompare (root->left);
3998 root->right = optimizeCompare (root->right);
4002 /* if left & right are the same then depending
4003 of the operation do */
4004 if (isAstEqual (root->left, root->right))
4006 switch (root->opval.op)
4011 optExpr = newAst_VALUE (constVal ("0"));
4016 optExpr = newAst_VALUE (constVal ("1"));
4020 return decorateType (optExpr);
4023 vleft = (root->left->type == EX_VALUE ?
4024 root->left->opval.val : NULL);
4026 vright = (root->right->type == EX_VALUE ?
4027 root->right->opval.val : NULL);
4029 /* if left is a BITVAR in BITSPACE */
4030 /* and right is a LITERAL then opt- */
4031 /* imize else do nothing */
4032 if (vleft && vright &&
4033 IS_BITVAR (vleft->etype) &&
4034 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4035 IS_LITERAL (vright->etype))
4038 /* if right side > 1 then comparison may never succeed */
4039 if ((litValue = (int) floatFromVal (vright)) > 1)
4041 werror (W_BAD_COMPARE);
4047 switch (root->opval.op)
4049 case '>': /* bit value greater than 1 cannot be */
4050 werror (W_BAD_COMPARE);
4054 case '<': /* bit value < 1 means 0 */
4056 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4059 case LE_OP: /* bit value <= 1 means no check */
4060 optExpr = newAst_VALUE (vright);
4063 case GE_OP: /* bit value >= 1 means only check for = */
4065 optExpr = newAst_VALUE (vleft);
4070 { /* literal is zero */
4071 switch (root->opval.op)
4073 case '<': /* bit value < 0 cannot be */
4074 werror (W_BAD_COMPARE);
4078 case '>': /* bit value > 0 means 1 */
4080 optExpr = newAst_VALUE (vleft);
4083 case LE_OP: /* bit value <= 0 means no check */
4084 case GE_OP: /* bit value >= 0 means no check */
4085 werror (W_BAD_COMPARE);
4089 case EQ_OP: /* bit == 0 means ! of bit */
4090 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4094 return decorateType (resolveSymbols (optExpr));
4095 } /* end-of-if of BITVAR */
4100 /*-----------------------------------------------------------------*/
4101 /* addSymToBlock : adds the symbol to the first block we find */
4102 /*-----------------------------------------------------------------*/
4104 addSymToBlock (symbol * sym, ast * tree)
4106 /* reached end of tree or a leaf */
4107 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4111 if (IS_AST_OP (tree) &&
4112 tree->opval.op == BLOCK)
4115 symbol *lsym = copySymbol (sym);
4117 lsym->next = AST_VALUES (tree, sym);
4118 AST_VALUES (tree, sym) = lsym;
4122 addSymToBlock (sym, tree->left);
4123 addSymToBlock (sym, tree->right);
4126 /*-----------------------------------------------------------------*/
4127 /* processRegParms - do processing for register parameters */
4128 /*-----------------------------------------------------------------*/
4130 processRegParms (value * args, ast * body)
4134 if (IS_REGPARM (args->etype))
4135 addSymToBlock (args->sym, body);
4140 /*-----------------------------------------------------------------*/
4141 /* resetParmKey - resets the operandkeys for the symbols */
4142 /*-----------------------------------------------------------------*/
4143 DEFSETFUNC (resetParmKey)
4154 /*-----------------------------------------------------------------*/
4155 /* createFunction - This is the key node that calls the iCode for */
4156 /* generating the code for a function. Note code */
4157 /* is generated function by function, later when */
4158 /* add inter-procedural analysis this will change */
4159 /*-----------------------------------------------------------------*/
4161 createFunction (symbol * name, ast * body)
4167 iCode *piCode = NULL;
4169 /* if check function return 0 then some problem */
4170 if (checkFunction (name) == 0)
4173 /* create a dummy block if none exists */
4175 body = newNode (BLOCK, NULL, NULL);
4179 /* check if the function name already in the symbol table */
4180 if ((csym = findSym (SymbolTab, NULL, name->name)))
4183 /* special case for compiler defined functions
4184 we need to add the name to the publics list : this
4185 actually means we are now compiling the compiler
4189 addSet (&publics, name);
4195 allocVariables (name);
4197 name->lastLine = yylineno;
4199 processFuncArgs (currFunc, 0);
4201 /* set the stack pointer */
4202 /* PENDING: check this for the mcs51 */
4203 stackPtr = -port->stack.direction * port->stack.call_overhead;
4204 if (IS_ISR (name->etype))
4205 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4206 if (IS_RENT (name->etype) || options.stackAuto)
4207 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4209 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4211 fetype = getSpec (name->type); /* get the specifier for the function */
4212 /* if this is a reentrant function then */
4213 if (IS_RENT (fetype))
4216 allocParms (name->args); /* allocate the parameters */
4218 /* do processing for parameters that are passed in registers */
4219 processRegParms (name->args, body);
4221 /* set the stack pointer */
4225 /* allocate & autoinit the block variables */
4226 processBlockVars (body, &stack, ALLOCATE);
4228 /* save the stack information */
4229 if (options.useXstack)
4230 name->xstack = SPEC_STAK (fetype) = stack;
4232 name->stack = SPEC_STAK (fetype) = stack;
4234 /* name needs to be mangled */
4235 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4237 body = resolveSymbols (body); /* resolve the symbols */
4238 body = decorateType (body); /* propagateType & do semantic checks */
4240 ex = newAst_VALUE (symbolVal (name)); /* create name */
4241 ex = newNode (FUNCTION, ex, body);
4242 ex->values.args = name->args;
4246 werror (E_FUNC_NO_CODE, name->name);
4250 /* create the node & generate intermediate code */
4252 codeOutFile = code->oFile;
4253 piCode = iCodeFromAst (ex);
4257 werror (E_FUNC_NO_CODE, name->name);
4261 eBBlockFromiCode (piCode);
4263 /* if there are any statics then do them */
4266 GcurMemmap = statsg;
4267 codeOutFile = statsg->oFile;
4268 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4274 /* dealloc the block variables */
4275 processBlockVars (body, &stack, DEALLOCATE);
4276 /* deallocate paramaters */
4277 deallocParms (name->args);
4279 if (IS_RENT (fetype))
4282 /* we are done freeup memory & cleanup */
4287 addSet (&operKeyReset, name);
4288 applyToSet (operKeyReset, resetParmKey);
4291 cdbStructBlock (1, cdbFile);
4293 cleanUpLevel (LabelTab, 0);
4294 cleanUpBlock (StructTab, 1);
4295 cleanUpBlock (TypedefTab, 1);
4297 xstack->syms = NULL;
4298 istack->syms = NULL;
4303 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4304 /*-----------------------------------------------------------------*/
4305 /* ast_print : prints the ast (for debugging purposes) */
4306 /*-----------------------------------------------------------------*/
4308 void ast_print (ast * tree, FILE *outfile, int indent)
4313 /* can print only decorated trees */
4314 if (!tree->decorated) return;
4316 /* if any child is an error | this one is an error do nothing */
4317 if (tree->isError ||
4318 (tree->left && tree->left->isError) ||
4319 (tree->right && tree->right->isError)) {
4320 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4324 /* print the line */
4325 /* if not block & function */
4326 if (tree->type == EX_OP &&
4327 (tree->opval.op != FUNCTION &&
4328 tree->opval.op != BLOCK &&
4329 tree->opval.op != NULLOP)) {
4332 if (tree->opval.op == FUNCTION) {
4333 fprintf(outfile,"FUNCTION (%p) type (",tree);
4334 printTypeChain (tree->ftype,outfile);
4335 fprintf(outfile,")\n");
4336 ast_print(tree->left,outfile,indent+4);
4337 ast_print(tree->right,outfile,indent+4);
4340 if (tree->opval.op == BLOCK) {
4341 symbol *decls = tree->values.sym;
4342 fprintf(outfile,"{\n");
4344 INDENT(indent+4,outfile);
4345 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4346 printTypeChain(decls->type,outfile);
4347 fprintf(outfile,")\n");
4349 decls = decls->next;
4351 ast_print(tree->right,outfile,indent+4);
4352 fprintf(outfile,"}\n");
4355 if (tree->opval.op == NULLOP) {
4356 fprintf(outfile,"\n");
4357 ast_print(tree->left,outfile,indent);
4358 fprintf(outfile,"\n");
4359 ast_print(tree->right,outfile,indent);
4362 INDENT(indent,outfile);
4364 /*------------------------------------------------------------------*/
4365 /*----------------------------*/
4366 /* leaf has been reached */
4367 /*----------------------------*/
4368 /* if this is of type value */
4369 /* just get the type */
4370 if (tree->type == EX_VALUE) {
4372 if (IS_LITERAL (tree->opval.val->etype)) {
4373 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4374 (int) floatFromVal(tree->opval.val),
4375 (int) floatFromVal(tree->opval.val),
4376 floatFromVal(tree->opval.val));
4377 } else if (tree->opval.val->sym) {
4378 /* if the undefined flag is set then give error message */
4379 if (tree->opval.val->sym->undefined) {
4380 fprintf(outfile,"UNDEFINED SYMBOL ");
4382 fprintf(outfile,"SYMBOL ");
4384 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4387 fprintf(outfile," type (");
4388 printTypeChain(tree->ftype,outfile);
4389 fprintf(outfile,")\n");
4391 fprintf(outfile,"\n");
4396 /* if type link for the case of cast */
4397 if (tree->type == EX_LINK) {
4398 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4399 printTypeChain(tree->opval.lnk,outfile);
4400 fprintf(outfile,")\n");
4405 /* depending on type of operator do */
4407 switch (tree->opval.op) {
4408 /*------------------------------------------------------------------*/
4409 /*----------------------------*/
4411 /*----------------------------*/
4413 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4414 printTypeChain(tree->ftype,outfile);
4415 fprintf(outfile,")\n");
4416 ast_print(tree->left,outfile,indent+4);
4417 ast_print(tree->right,outfile,indent+4);
4420 /*------------------------------------------------------------------*/
4421 /*----------------------------*/
4423 /*----------------------------*/
4425 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4426 printTypeChain(tree->ftype,outfile);
4427 fprintf(outfile,")\n");
4428 ast_print(tree->left,outfile,indent+4);
4429 ast_print(tree->right,outfile,indent+4);
4432 /*------------------------------------------------------------------*/
4433 /*----------------------------*/
4434 /* struct/union pointer */
4435 /*----------------------------*/
4437 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4438 printTypeChain(tree->ftype,outfile);
4439 fprintf(outfile,")\n");
4440 ast_print(tree->left,outfile,indent+4);
4441 ast_print(tree->right,outfile,indent+4);
4444 /*------------------------------------------------------------------*/
4445 /*----------------------------*/
4446 /* ++/-- operation */
4447 /*----------------------------*/
4448 case INC_OP: /* incerement operator unary so left only */
4449 fprintf(outfile,"INC_OP (%p) type (",tree);
4450 printTypeChain(tree->ftype,outfile);
4451 fprintf(outfile,")\n");
4452 ast_print(tree->left,outfile,indent+4);
4456 fprintf(outfile,"DEC_OP (%p) type (",tree);
4457 printTypeChain(tree->ftype,outfile);
4458 fprintf(outfile,")\n");
4459 ast_print(tree->left,outfile,indent+4);
4462 /*------------------------------------------------------------------*/
4463 /*----------------------------*/
4465 /*----------------------------*/
4468 fprintf(outfile,"& (%p) type (",tree);
4469 printTypeChain(tree->ftype,outfile);
4470 fprintf(outfile,")\n");
4471 ast_print(tree->left,outfile,indent+4);
4472 ast_print(tree->right,outfile,indent+4);
4474 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4475 printTypeChain(tree->ftype,outfile);
4476 fprintf(outfile,")\n");
4477 ast_print(tree->left,outfile,indent+4);
4478 ast_print(tree->right,outfile,indent+4);
4481 /*----------------------------*/
4483 /*----------------------------*/
4485 fprintf(outfile,"OR (%p) type (",tree);
4486 printTypeChain(tree->ftype,outfile);
4487 fprintf(outfile,")\n");
4488 ast_print(tree->left,outfile,indent+4);
4489 ast_print(tree->right,outfile,indent+4);
4491 /*------------------------------------------------------------------*/
4492 /*----------------------------*/
4494 /*----------------------------*/
4496 fprintf(outfile,"XOR (%p) type (",tree);
4497 printTypeChain(tree->ftype,outfile);
4498 fprintf(outfile,")\n");
4499 ast_print(tree->left,outfile,indent+4);
4500 ast_print(tree->right,outfile,indent+4);
4503 /*------------------------------------------------------------------*/
4504 /*----------------------------*/
4506 /*----------------------------*/
4508 fprintf(outfile,"DIV (%p) type (",tree);
4509 printTypeChain(tree->ftype,outfile);
4510 fprintf(outfile,")\n");
4511 ast_print(tree->left,outfile,indent+4);
4512 ast_print(tree->right,outfile,indent+4);
4514 /*------------------------------------------------------------------*/
4515 /*----------------------------*/
4517 /*----------------------------*/
4519 fprintf(outfile,"MOD (%p) type (",tree);
4520 printTypeChain(tree->ftype,outfile);
4521 fprintf(outfile,")\n");
4522 ast_print(tree->left,outfile,indent+4);
4523 ast_print(tree->right,outfile,indent+4);
4526 /*------------------------------------------------------------------*/
4527 /*----------------------------*/
4528 /* address dereference */
4529 /*----------------------------*/
4530 case '*': /* can be unary : if right is null then unary operation */
4532 fprintf(outfile,"DEREF (%p) type (",tree);
4533 printTypeChain(tree->ftype,outfile);
4534 fprintf(outfile,")\n");
4535 ast_print(tree->left,outfile,indent+4);
4538 /*------------------------------------------------------------------*/
4539 /*----------------------------*/
4540 /* multiplication */
4541 /*----------------------------*/
4542 fprintf(outfile,"MULT (%p) type (",tree);
4543 printTypeChain(tree->ftype,outfile);
4544 fprintf(outfile,")\n");
4545 ast_print(tree->left,outfile,indent+4);
4546 ast_print(tree->right,outfile,indent+4);
4550 /*------------------------------------------------------------------*/
4551 /*----------------------------*/
4552 /* unary '+' operator */
4553 /*----------------------------*/
4557 fprintf(outfile,"UPLUS (%p) type (",tree);
4558 printTypeChain(tree->ftype,outfile);
4559 fprintf(outfile,")\n");
4560 ast_print(tree->left,outfile,indent+4);
4562 /*------------------------------------------------------------------*/
4563 /*----------------------------*/
4565 /*----------------------------*/
4566 fprintf(outfile,"ADD (%p) type (",tree);
4567 printTypeChain(tree->ftype,outfile);
4568 fprintf(outfile,")\n");
4569 ast_print(tree->left,outfile,indent+4);
4570 ast_print(tree->right,outfile,indent+4);
4573 /*------------------------------------------------------------------*/
4574 /*----------------------------*/
4576 /*----------------------------*/
4577 case '-': /* can be unary */
4579 fprintf(outfile,"UMINUS (%p) type (",tree);
4580 printTypeChain(tree->ftype,outfile);
4581 fprintf(outfile,")\n");
4582 ast_print(tree->left,outfile,indent+4);
4584 /*------------------------------------------------------------------*/
4585 /*----------------------------*/
4587 /*----------------------------*/
4588 fprintf(outfile,"SUB (%p) type (",tree);
4589 printTypeChain(tree->ftype,outfile);
4590 fprintf(outfile,")\n");
4591 ast_print(tree->left,outfile,indent+4);
4592 ast_print(tree->right,outfile,indent+4);
4595 /*------------------------------------------------------------------*/
4596 /*----------------------------*/
4598 /*----------------------------*/
4600 fprintf(outfile,"COMPL (%p) type (",tree);
4601 printTypeChain(tree->ftype,outfile);
4602 fprintf(outfile,")\n");
4603 ast_print(tree->left,outfile,indent+4);
4605 /*------------------------------------------------------------------*/
4606 /*----------------------------*/
4608 /*----------------------------*/
4610 fprintf(outfile,"NOT (%p) type (",tree);
4611 printTypeChain(tree->ftype,outfile);
4612 fprintf(outfile,")\n");
4613 ast_print(tree->left,outfile,indent+4);
4615 /*------------------------------------------------------------------*/
4616 /*----------------------------*/
4618 /*----------------------------*/
4620 fprintf(outfile,"RRC (%p) type (",tree);
4621 printTypeChain(tree->ftype,outfile);
4622 fprintf(outfile,")\n");
4623 ast_print(tree->left,outfile,indent+4);
4627 fprintf(outfile,"RLC (%p) type (",tree);
4628 printTypeChain(tree->ftype,outfile);
4629 fprintf(outfile,")\n");
4630 ast_print(tree->left,outfile,indent+4);
4633 fprintf(outfile,"GETHBIT (%p) type (",tree);
4634 printTypeChain(tree->ftype,outfile);
4635 fprintf(outfile,")\n");
4636 ast_print(tree->left,outfile,indent+4);
4639 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4640 printTypeChain(tree->ftype,outfile);
4641 fprintf(outfile,")\n");
4642 ast_print(tree->left,outfile,indent+4);
4643 ast_print(tree->right,outfile,indent+4);
4646 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4647 printTypeChain(tree->ftype,outfile);
4648 fprintf(outfile,")\n");
4649 ast_print(tree->left,outfile,indent+4);
4650 ast_print(tree->right,outfile,indent+4);
4652 /*------------------------------------------------------------------*/
4653 /*----------------------------*/
4655 /*----------------------------*/
4656 case CAST: /* change the type */
4657 fprintf(outfile,"CAST (%p) type (",tree);
4658 printTypeChain(tree->ftype,outfile);
4659 fprintf(outfile,")\n");
4660 ast_print(tree->right,outfile,indent+4);
4664 fprintf(outfile,"ANDAND (%p) type (",tree);
4665 printTypeChain(tree->ftype,outfile);
4666 fprintf(outfile,")\n");
4667 ast_print(tree->left,outfile,indent+4);
4668 ast_print(tree->right,outfile,indent+4);
4671 fprintf(outfile,"OROR (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+4);
4675 ast_print(tree->right,outfile,indent+4);
4678 /*------------------------------------------------------------------*/
4679 /*----------------------------*/
4680 /* comparison operators */
4681 /*----------------------------*/
4683 fprintf(outfile,"GT(>) (%p) type (",tree);
4684 printTypeChain(tree->ftype,outfile);
4685 fprintf(outfile,")\n");
4686 ast_print(tree->left,outfile,indent+4);
4687 ast_print(tree->right,outfile,indent+4);
4690 fprintf(outfile,"LT(<) (%p) type (",tree);
4691 printTypeChain(tree->ftype,outfile);
4692 fprintf(outfile,")\n");
4693 ast_print(tree->left,outfile,indent+4);
4694 ast_print(tree->right,outfile,indent+4);
4697 fprintf(outfile,"LE(<=) (%p) type (",tree);
4698 printTypeChain(tree->ftype,outfile);
4699 fprintf(outfile,")\n");
4700 ast_print(tree->left,outfile,indent+4);
4701 ast_print(tree->right,outfile,indent+4);
4704 fprintf(outfile,"GE(>=) (%p) type (",tree);
4705 printTypeChain(tree->ftype,outfile);
4706 fprintf(outfile,")\n");
4707 ast_print(tree->left,outfile,indent+4);
4708 ast_print(tree->right,outfile,indent+4);
4711 fprintf(outfile,"EQ(==) (%p) type (",tree);
4712 printTypeChain(tree->ftype,outfile);
4713 fprintf(outfile,")\n");
4714 ast_print(tree->left,outfile,indent+4);
4715 ast_print(tree->right,outfile,indent+4);
4718 fprintf(outfile,"NE(!=) (%p) type (",tree);
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->left,outfile,indent+4);
4722 ast_print(tree->right,outfile,indent+4);
4723 /*------------------------------------------------------------------*/
4724 /*----------------------------*/
4726 /*----------------------------*/
4727 case SIZEOF: /* evaluate wihout code generation */
4728 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4731 /*------------------------------------------------------------------*/
4732 /*----------------------------*/
4733 /* conditional operator '?' */
4734 /*----------------------------*/
4736 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4737 printTypeChain(tree->ftype,outfile);
4738 fprintf(outfile,")\n");
4739 ast_print(tree->left,outfile,indent+4);
4740 ast_print(tree->right,outfile,indent+4);
4744 fprintf(outfile,"COLON(:) (%p) type (",tree);
4745 printTypeChain(tree->ftype,outfile);
4746 fprintf(outfile,")\n");
4747 ast_print(tree->left,outfile,indent+4);
4748 ast_print(tree->right,outfile,indent+4);
4751 /*------------------------------------------------------------------*/
4752 /*----------------------------*/
4753 /* assignment operators */
4754 /*----------------------------*/
4756 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4757 printTypeChain(tree->ftype,outfile);
4758 fprintf(outfile,")\n");
4759 ast_print(tree->left,outfile,indent+4);
4760 ast_print(tree->right,outfile,indent+4);
4763 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+4);
4767 ast_print(tree->right,outfile,indent+4);
4770 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4771 printTypeChain(tree->ftype,outfile);
4772 fprintf(outfile,")\n");
4773 ast_print(tree->left,outfile,indent+4);
4774 ast_print(tree->right,outfile,indent+4);
4777 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4778 printTypeChain(tree->ftype,outfile);
4779 fprintf(outfile,")\n");
4780 ast_print(tree->left,outfile,indent+4);
4781 ast_print(tree->right,outfile,indent+4);
4784 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4785 printTypeChain(tree->ftype,outfile);
4786 fprintf(outfile,")\n");
4787 ast_print(tree->left,outfile,indent+4);
4788 ast_print(tree->right,outfile,indent+4);
4791 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4792 printTypeChain(tree->ftype,outfile);
4793 fprintf(outfile,")\n");
4794 ast_print(tree->left,outfile,indent+4);
4795 ast_print(tree->right,outfile,indent+4);
4798 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4799 printTypeChain(tree->ftype,outfile);
4800 fprintf(outfile,")\n");
4801 ast_print(tree->left,outfile,indent+4);
4802 ast_print(tree->right,outfile,indent+4);
4804 /*------------------------------------------------------------------*/
4805 /*----------------------------*/
4807 /*----------------------------*/
4809 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4810 printTypeChain(tree->ftype,outfile);
4811 fprintf(outfile,")\n");
4812 ast_print(tree->left,outfile,indent+4);
4813 ast_print(tree->right,outfile,indent+4);
4815 /*------------------------------------------------------------------*/
4816 /*----------------------------*/
4818 /*----------------------------*/
4820 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4821 printTypeChain(tree->ftype,outfile);
4822 fprintf(outfile,")\n");
4823 ast_print(tree->left,outfile,indent+4);
4824 ast_print(tree->right,outfile,indent+4);
4826 /*------------------------------------------------------------------*/
4827 /*----------------------------*/
4828 /* straight assignemnt */
4829 /*----------------------------*/
4831 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4832 printTypeChain(tree->ftype,outfile);
4833 fprintf(outfile,")\n");
4834 ast_print(tree->left,outfile,indent+4);
4835 ast_print(tree->right,outfile,indent+4);
4837 /*------------------------------------------------------------------*/
4838 /*----------------------------*/
4839 /* comma operator */
4840 /*----------------------------*/
4842 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4843 printTypeChain(tree->ftype,outfile);
4844 fprintf(outfile,")\n");
4845 ast_print(tree->left,outfile,indent+4);
4846 ast_print(tree->right,outfile,indent+4);
4848 /*------------------------------------------------------------------*/
4849 /*----------------------------*/
4851 /*----------------------------*/
4854 fprintf(outfile,"CALL (%p) type (",tree);
4855 printTypeChain(tree->ftype,outfile);
4856 fprintf(outfile,")\n");
4857 ast_print(tree->left,outfile,indent+4);
4858 ast_print(tree->right,outfile,indent+4);
4861 fprintf(outfile,"PARM ");
4862 ast_print(tree->left,outfile,indent+4);
4863 if (tree->right && !IS_AST_PARAM(tree->right)) {
4864 fprintf(outfile,"PARM ");
4865 ast_print(tree->right,outfile,indent+4);
4868 /*------------------------------------------------------------------*/
4869 /*----------------------------*/
4870 /* return statement */
4871 /*----------------------------*/
4873 fprintf(outfile,"RETURN (%p) type (",tree);
4874 printTypeChain(tree->right->ftype,outfile);
4875 fprintf(outfile,")\n");
4876 ast_print(tree->right,outfile,indent+4);
4878 /*------------------------------------------------------------------*/
4879 /*----------------------------*/
4880 /* label statement */
4881 /*----------------------------*/
4883 fprintf(outfile,"LABEL (%p)",tree);
4884 ast_print(tree->left,outfile,indent+4);
4885 ast_print(tree->right,outfile,indent);
4887 /*------------------------------------------------------------------*/
4888 /*----------------------------*/
4889 /* switch statement */
4890 /*----------------------------*/
4894 fprintf(outfile,"SWITCH (%p) ",tree);
4895 ast_print(tree->left,outfile,0);
4896 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4897 INDENT(indent+4,outfile);
4898 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4899 (int) floatFromVal(val),
4900 tree->values.switchVals.swNum,
4901 (int) floatFromVal(val));
4903 ast_print(tree->right,outfile,indent);
4906 /*------------------------------------------------------------------*/
4907 /*----------------------------*/
4909 /*----------------------------*/
4911 ast_print(tree->left,outfile,indent);
4912 INDENT(indent,outfile);
4913 fprintf(outfile,"IF (%p) \n",tree);
4914 if (tree->trueLabel) {
4915 INDENT(indent,outfile);
4916 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4918 if (tree->falseLabel) {
4919 INDENT(indent,outfile);
4920 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4922 ast_print(tree->right,outfile,indent);
4924 /*------------------------------------------------------------------*/
4925 /*----------------------------*/
4927 /*----------------------------*/
4929 fprintf(outfile,"FOR (%p) \n",tree);
4930 if (AST_FOR( tree, initExpr)) {
4931 INDENT(indent+4,outfile);
4932 fprintf(outfile,"INIT EXPR ");
4933 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4935 if (AST_FOR( tree, condExpr)) {
4936 INDENT(indent+4,outfile);
4937 fprintf(outfile,"COND EXPR ");
4938 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4940 if (AST_FOR( tree, loopExpr)) {
4941 INDENT(indent+4,outfile);
4942 fprintf(outfile,"LOOP EXPR ");
4943 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4945 fprintf(outfile,"FOR LOOP BODY \n");
4946 ast_print(tree->left,outfile,indent+4);
4955 ast_print(t,stdout,1);