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 *);
58 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
63 printTypeChain (tree->ftype, stdout);
68 /*-----------------------------------------------------------------*/
69 /* newAst - creates a fresh node for an expression tree */
70 /*-----------------------------------------------------------------*/
73 newAst (int type, void *op)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
87 /* depending on the type */
91 ex->opval.val = (value *) op;
94 ex->opval.op = (long) op;
97 ex->opval.lnk = (sym_link *) op;
100 ex->opval.stmnt = (unsigned) op;
108 newAst_ (unsigned type)
111 static int oldLineno = 0;
113 ex = Safe_alloc ( sizeof (ast));
116 ex->lineno = (noLineno ? oldLineno : yylineno);
117 ex->filename = currFname;
118 ex->level = NestLevel;
119 ex->block = currBlockno;
120 ex->initMode = inInitMode;
125 newAst_VALUE (value * val)
127 ast *ex = newAst_ (EX_VALUE);
133 newAst_OP (unsigned op)
135 ast *ex = newAst_ (EX_OP);
141 newAst_LINK (sym_link * val)
143 ast *ex = newAst_ (EX_LINK);
149 newAst_STMNT (unsigned val)
151 ast *ex = newAst_ (EX_STMNT);
152 ex->opval.stmnt = val;
156 /*-----------------------------------------------------------------*/
157 /* newNode - creates a new node */
158 /*-----------------------------------------------------------------*/
160 newNode (long op, ast * left, ast * right)
171 /*-----------------------------------------------------------------*/
172 /* newIfxNode - creates a new Ifx Node */
173 /*-----------------------------------------------------------------*/
175 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
179 /* if this is a literal then we already know the result */
180 if (condAst->etype && IS_LITERAL (condAst->etype))
182 /* then depending on the expression value */
183 if (floatFromVal (condAst->opval.val))
184 ifxNode = newNode (GOTO,
185 newAst_VALUE (symbolVal (trueLabel)),
188 ifxNode = newNode (GOTO,
189 newAst_VALUE (symbolVal (falseLabel)),
194 ifxNode = newNode (IFX, condAst, NULL);
195 ifxNode->trueLabel = trueLabel;
196 ifxNode->falseLabel = falseLabel;
202 /*-----------------------------------------------------------------*/
203 /* copyAstValues - copies value portion of ast if needed */
204 /*-----------------------------------------------------------------*/
206 copyAstValues (ast * dest, ast * src)
208 switch (src->opval.op)
211 dest->values.sym = copySymbolChain (src->values.sym);
215 dest->values.switchVals.swVals =
216 copyValue (src->values.switchVals.swVals);
217 dest->values.switchVals.swDefault =
218 src->values.switchVals.swDefault;
219 dest->values.switchVals.swNum =
220 src->values.switchVals.swNum;
224 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
225 strcpy (dest->values.inlineasm, src->values.inlineasm);
229 dest->values.constlist = copyLiteralList(src->values.constlist);
233 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
234 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
235 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
236 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
237 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
238 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
239 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
244 /*-----------------------------------------------------------------*/
245 /* copyAst - makes a copy of a given astession */
246 /*-----------------------------------------------------------------*/
255 dest = Safe_alloc ( sizeof (ast));
257 dest->type = src->type;
258 dest->lineno = src->lineno;
259 dest->level = src->level;
260 dest->funcName = src->funcName;
263 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
265 /* if this is a leaf */
267 if (src->type == EX_VALUE)
269 dest->opval.val = copyValue (src->opval.val);
274 if (src->type == EX_LINK)
276 dest->opval.lnk = copyLinkChain (src->opval.lnk);
280 dest->opval.op = src->opval.op;
282 /* if this is a node that has special values */
283 copyAstValues (dest, src);
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 /* setup return value */
546 sym->type = newLink ();
547 DCL_TYPE (sym->type) = FUNCTION;
548 sym->type->next = copyLinkChain (type);
549 sym->etype = getSpec (sym->type);
550 FUNC_ISREENT(sym->type) = rent;
552 /* if arguments required */
556 args = FUNC_ARGS(sym->type) = newValue ();
560 args->type = copyLinkChain (argType);
561 args->etype = getSpec (args->type);
562 SPEC_EXTR(args->etype)=1;
565 args = args->next = newValue ();
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
611 /* if none of them exist */
612 if (!defParm && !actParm)
616 if (getenv("DEBUG_SANITY")) {
617 fprintf (stderr, "processParms: %s ", defParm->name);
619 /* make sure the type is complete and sane */
620 checkTypeSanity(defParm->etype, defParm->name);
623 /* if the function is being called via a pointer & */
624 /* it has not been defined a reentrant then we cannot */
625 /* have parameters */
626 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
628 werror (W_NONRENT_ARGS);
632 /* if defined parameters ended but actual parameters */
633 /* exist and this is not defined as a variable arg */
634 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
636 werror (E_TOO_MANY_PARMS);
640 /* if defined parameters present but no actual parameters */
641 if (defParm && !actParm)
643 werror (E_TOO_FEW_PARMS);
647 if (IS_VOID(actParm->ftype)) {
648 werror (E_VOID_VALUE_USED);
652 /* If this is a varargs function... */
653 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
658 if (IS_CAST_OP (actParm)
659 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
661 /* Parameter was explicitly typecast; don't touch it. */
665 ftype = actParm->ftype;
667 /* If it's a small integer, upcast to int. */
668 if (IS_INTEGRAL (ftype)
669 && (getSize (ftype) < (unsigned) INTSIZE))
671 newType = newAst_LINK(INTTYPE);
674 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
676 newType = newAst_LINK (copyLinkChain(ftype));
677 DCL_TYPE (newType->opval.lnk) = GPOINTER;
680 if (IS_AGGREGATE (ftype))
682 newType = newAst_LINK (copyLinkChain (ftype));
683 DCL_TYPE (newType->opval.lnk) = GPOINTER;
687 /* cast required; change this op to a cast. */
688 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
690 actParm->type = EX_OP;
691 actParm->opval.op = CAST;
692 actParm->left = newType;
693 actParm->right = parmCopy;
694 decorateType (actParm);
696 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
698 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
699 processParms (func, NULL, actParm->right, parmNumber, rightmost));
704 /* if defined parameters ended but actual has not & */
706 if (!defParm && actParm &&
707 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
710 resolveSymbols (actParm);
711 /* if this is a PARAM node then match left & right */
712 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
714 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
715 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
719 /* If we have found a value node by following only right-hand links,
720 * then we know that there are no more values after us.
722 * Therefore, if there are more defined parameters, the caller didn't
725 if (rightmost && defParm->next)
727 werror (E_TOO_FEW_PARMS);
732 /* the parameter type must be at least castable */
733 if (compareType (defParm->type, actParm->ftype) == 0) {
734 werror (E_INCOMPAT_TYPES);
735 printFromToType (actParm->ftype, defParm->type);
739 /* if the parameter is castable then add the cast */
740 if (compareType (defParm->type, actParm->ftype) < 0)
742 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
744 /* now change the current one to a cast */
745 actParm->type = EX_OP;
746 actParm->opval.op = CAST;
747 actParm->left = newAst_LINK (defParm->type);
748 actParm->right = pTree;
749 actParm->etype = defParm->etype;
750 actParm->ftype = defParm->type;
751 actParm->decorated=0; /* force typechecking */
752 decorateType (actParm);
755 /* make a copy and change the regparm type to the defined parm */
756 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
757 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
761 /*-----------------------------------------------------------------*/
762 /* createIvalType - generates ival for basic types */
763 /*-----------------------------------------------------------------*/
765 createIvalType (ast * sym, sym_link * type, initList * ilist)
769 /* if initList is deep */
770 if (ilist->type == INIT_DEEP)
771 ilist = ilist->init.deep;
773 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
774 return decorateType (newNode ('=', sym, iExpr));
777 /*-----------------------------------------------------------------*/
778 /* createIvalStruct - generates initial value for structures */
779 /*-----------------------------------------------------------------*/
781 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
788 sflds = SPEC_STRUCT (type)->fields;
789 if (ilist->type != INIT_DEEP)
791 werror (E_INIT_STRUCT, "");
795 iloop = ilist->init.deep;
797 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
799 /* if we have come to end */
803 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
804 lAst = decorateType (resolveSymbols (lAst));
805 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
811 /*-----------------------------------------------------------------*/
812 /* createIvalArray - generates code for array initialization */
813 /*-----------------------------------------------------------------*/
815 createIvalArray (ast * sym, sym_link * type, initList * ilist)
819 int lcnt = 0, size = 0;
820 literalList *literalL;
822 /* take care of the special case */
823 /* array of characters can be init */
825 if (IS_CHAR (type->next))
826 if ((rast = createIvalCharPtr (sym,
828 decorateType (resolveSymbols (list2expr (ilist))))))
830 return decorateType (resolveSymbols (rast));
832 /* not the special case */
833 if (ilist->type != INIT_DEEP)
835 werror (E_INIT_STRUCT, "");
839 iloop = ilist->init.deep;
840 lcnt = DCL_ELEM (type);
842 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
846 aSym = decorateType (resolveSymbols(sym));
848 rast = newNode(ARRAYINIT, aSym, NULL);
849 rast->values.constlist = literalL;
851 // Make sure size is set to length of initializer list.
858 if (lcnt && size > lcnt)
860 // Array size was specified, and we have more initializers than needed.
861 char *name=sym->opval.val->sym->name;
862 int lineno=sym->opval.val->sym->lineDef;
864 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
873 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
874 aSym = decorateType (resolveSymbols (aSym));
875 rast = createIval (aSym, type->next, iloop, rast);
876 iloop = (iloop ? iloop->next : NULL);
882 /* no of elements given and we */
883 /* have generated for all of them */
886 // there has to be a better way
887 char *name=sym->opval.val->sym->name;
888 int lineno=sym->opval.val->sym->lineDef;
889 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
896 /* if we have not been given a size */
897 if (!DCL_ELEM (type))
899 DCL_ELEM (type) = size;
902 return decorateType (resolveSymbols (rast));
906 /*-----------------------------------------------------------------*/
907 /* createIvalCharPtr - generates initial values for char pointers */
908 /*-----------------------------------------------------------------*/
910 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
914 /* if this is a pointer & right is a literal array then */
915 /* just assignment will do */
916 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
917 SPEC_SCLS (iexpr->etype) == S_CODE)
918 && IS_ARRAY (iexpr->ftype)))
919 return newNode ('=', sym, iexpr);
921 /* left side is an array so we have to assign each */
923 if ((IS_LITERAL (iexpr->etype) ||
924 SPEC_SCLS (iexpr->etype) == S_CODE)
925 && IS_ARRAY (iexpr->ftype))
927 /* for each character generate an assignment */
928 /* to the array element */
929 char *s = SPEC_CVAL (iexpr->etype).v_char;
934 rast = newNode (NULLOP,
938 newAst_VALUE (valueFromLit ((float) i))),
939 newAst_VALUE (valueFromLit (*s))));
943 rast = newNode (NULLOP,
947 newAst_VALUE (valueFromLit ((float) i))),
948 newAst_VALUE (valueFromLit (*s))));
949 return decorateType (resolveSymbols (rast));
955 /*-----------------------------------------------------------------*/
956 /* createIvalPtr - generates initial value for pointers */
957 /*-----------------------------------------------------------------*/
959 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
965 if (ilist->type == INIT_DEEP)
966 ilist = ilist->init.deep;
968 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
970 /* if character pointer */
971 if (IS_CHAR (type->next))
972 if ((rast = createIvalCharPtr (sym, type, iexpr)))
975 return newNode ('=', sym, iexpr);
978 /*-----------------------------------------------------------------*/
979 /* createIval - generates code for initial value */
980 /*-----------------------------------------------------------------*/
982 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
989 /* if structure then */
990 if (IS_STRUCT (type))
991 rast = createIvalStruct (sym, type, ilist);
993 /* if this is a pointer */
995 rast = createIvalPtr (sym, type, ilist);
997 /* if this is an array */
999 rast = createIvalArray (sym, type, ilist);
1001 /* if type is SPECIFIER */
1003 rast = createIvalType (sym, type, ilist);
1006 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1008 return decorateType (resolveSymbols (rast));
1011 /*-----------------------------------------------------------------*/
1012 /* initAggregates - initialises aggregate variables with initv */
1013 /*-----------------------------------------------------------------*/
1015 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1017 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1021 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1023 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1024 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1025 "with -mmcs51 and --model-large\n");
1029 if (SPEC_OCLS(sym->etype)==xdata &&
1030 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1033 newSym=copySymbol (sym);
1034 SPEC_OCLS(newSym->etype)=code;
1035 sprintf (newSym->name, "%s_init__", sym->name);
1036 sprintf (newSym->rname,"%s_init__", sym->rname);
1037 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1039 // emit it in the static segment
1040 addSet(&statsg->syms, newSym);
1042 // now memcpy() the entire array from cseg
1043 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1044 newAst_VALUE (symbolVal (sym)),
1045 newAst_VALUE (symbolVal (newSym)));
1046 return decorateType(resolveSymbols(ast));
1050 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1053 /*-----------------------------------------------------------------*/
1054 /* gatherAutoInit - creates assignment expressions for initial */
1056 /*-----------------------------------------------------------------*/
1058 gatherAutoInit (symbol * autoChain)
1065 for (sym = autoChain; sym; sym = sym->next)
1068 /* resolve the symbols in the ival */
1070 resolveIvalSym (sym->ival);
1072 /* if this is a static variable & has an */
1073 /* initial value the code needs to be lifted */
1074 /* here to the main portion since they can be */
1075 /* initialised only once at the start */
1076 if (IS_STATIC (sym->etype) && sym->ival &&
1077 SPEC_SCLS (sym->etype) != S_CODE)
1081 // this can only be a constant
1082 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1083 werror (E_CONST_EXPECTED);
1086 /* insert the symbol into the symbol table */
1087 /* with level = 0 & name = rname */
1088 newSym = copySymbol (sym);
1089 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1091 /* now lift the code to main */
1092 if (IS_AGGREGATE (sym->type))
1093 work = initAggregates (sym, sym->ival, NULL);
1095 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1096 list2expr (sym->ival));
1098 setAstLineno (work, sym->lineDef);
1102 staticAutos = newNode (NULLOP, staticAutos, work);
1109 /* if there is an initial value */
1110 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1112 if (IS_AGGREGATE (sym->type))
1113 work = initAggregates (sym, sym->ival, NULL);
1115 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1116 list2expr (sym->ival));
1118 setAstLineno (work, sym->lineDef);
1121 init = newNode (NULLOP, init, work);
1130 /*-----------------------------------------------------------------*/
1131 /* stringToSymbol - creates a symbol from a literal string */
1132 /*-----------------------------------------------------------------*/
1134 stringToSymbol (value * val)
1136 char name[SDCC_NAME_MAX + 1];
1137 static int charLbl = 0;
1140 sprintf (name, "_str_%d", charLbl++);
1141 sym = newSymbol (name, 0); /* make it @ level 0 */
1142 strcpy (sym->rname, name);
1144 /* copy the type from the value passed */
1145 sym->type = copyLinkChain (val->type);
1146 sym->etype = getSpec (sym->type);
1147 /* change to storage class & output class */
1148 SPEC_SCLS (sym->etype) = S_CODE;
1149 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1150 SPEC_STAT (sym->etype) = 1;
1151 /* make the level & block = 0 */
1152 sym->block = sym->level = 0;
1154 /* create an ival */
1155 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1160 allocVariables (sym);
1163 return symbolVal (sym);
1167 /*-----------------------------------------------------------------*/
1168 /* processBlockVars - will go thru the ast looking for block if */
1169 /* a block is found then will allocate the syms */
1170 /* will also gather the auto inits present */
1171 /*-----------------------------------------------------------------*/
1173 processBlockVars (ast * tree, int *stack, int action)
1178 /* if this is a block */
1179 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1183 if (action == ALLOCATE)
1185 *stack += allocVariables (tree->values.sym);
1186 autoInit = gatherAutoInit (tree->values.sym);
1188 /* if there are auto inits then do them */
1190 tree->left = newNode (NULLOP, autoInit, tree->left);
1192 else /* action is deallocate */
1193 deallocLocal (tree->values.sym);
1196 processBlockVars (tree->left, stack, action);
1197 processBlockVars (tree->right, stack, action);
1201 /*-----------------------------------------------------------------*/
1202 /* constExprValue - returns the value of a constant expression */
1203 /* or NULL if it is not a constant expression */
1204 /*-----------------------------------------------------------------*/
1206 constExprValue (ast * cexpr, int check)
1208 cexpr = decorateType (resolveSymbols (cexpr));
1210 /* if this is not a constant then */
1211 if (!IS_LITERAL (cexpr->ftype))
1213 /* then check if this is a literal array
1215 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1216 SPEC_CVAL (cexpr->etype).v_char &&
1217 IS_ARRAY (cexpr->ftype))
1219 value *val = valFromType (cexpr->ftype);
1220 SPEC_SCLS (val->etype) = S_LITERAL;
1221 val->sym = cexpr->opval.val->sym;
1222 val->sym->type = copyLinkChain (cexpr->ftype);
1223 val->sym->etype = getSpec (val->sym->type);
1224 strcpy (val->name, cexpr->opval.val->sym->rname);
1228 /* if we are casting a literal value then */
1229 if (IS_AST_OP (cexpr) &&
1230 cexpr->opval.op == CAST &&
1231 IS_LITERAL (cexpr->left->ftype))
1232 return valCastLiteral (cexpr->ftype,
1233 floatFromVal (cexpr->left->opval.val));
1235 if (IS_AST_VALUE (cexpr))
1236 return cexpr->opval.val;
1239 werror (E_CONST_EXPECTED, "found expression");
1244 /* return the value */
1245 return cexpr->opval.val;
1249 /*-----------------------------------------------------------------*/
1250 /* isLabelInAst - will return true if a given label is found */
1251 /*-----------------------------------------------------------------*/
1253 isLabelInAst (symbol * label, ast * tree)
1255 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1258 if (IS_AST_OP (tree) &&
1259 tree->opval.op == LABEL &&
1260 isSymbolEqual (AST_SYMBOL (tree->left), label))
1263 return isLabelInAst (label, tree->right) &&
1264 isLabelInAst (label, tree->left);
1268 /*-----------------------------------------------------------------*/
1269 /* isLoopCountable - return true if the loop count can be determi- */
1270 /* -ned at compile time . */
1271 /*-----------------------------------------------------------------*/
1273 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1274 symbol ** sym, ast ** init, ast ** end)
1277 /* the loop is considered countable if the following
1278 conditions are true :-
1280 a) initExpr :- <sym> = <const>
1281 b) condExpr :- <sym> < <const1>
1282 c) loopExpr :- <sym> ++
1285 /* first check the initExpr */
1286 if (IS_AST_OP (initExpr) &&
1287 initExpr->opval.op == '=' && /* is assignment */
1288 IS_AST_SYM_VALUE (initExpr->left))
1289 { /* left is a symbol */
1291 *sym = AST_SYMBOL (initExpr->left);
1292 *init = initExpr->right;
1297 /* for now the symbol has to be of
1299 if (!IS_INTEGRAL ((*sym)->type))
1302 /* now check condExpr */
1303 if (IS_AST_OP (condExpr))
1306 switch (condExpr->opval.op)
1309 if (IS_AST_SYM_VALUE (condExpr->left) &&
1310 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1311 IS_AST_LIT_VALUE (condExpr->right))
1313 *end = condExpr->right;
1319 if (IS_AST_OP (condExpr->left) &&
1320 condExpr->left->opval.op == '>' &&
1321 IS_AST_LIT_VALUE (condExpr->left->right) &&
1322 IS_AST_SYM_VALUE (condExpr->left->left) &&
1323 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1326 *end = newNode ('+', condExpr->left->right,
1327 newAst_VALUE (constVal ("1")));
1338 /* check loop expression is of the form <sym>++ */
1339 if (!IS_AST_OP (loopExpr))
1342 /* check if <sym> ++ */
1343 if (loopExpr->opval.op == INC_OP)
1349 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1350 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1357 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1358 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1366 if (loopExpr->opval.op == ADD_ASSIGN)
1369 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1370 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1371 IS_AST_LIT_VALUE (loopExpr->right) &&
1372 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1380 /*-----------------------------------------------------------------*/
1381 /* astHasVolatile - returns true if ast contains any volatile */
1382 /*-----------------------------------------------------------------*/
1384 astHasVolatile (ast * tree)
1389 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1392 if (IS_AST_OP (tree))
1393 return astHasVolatile (tree->left) ||
1394 astHasVolatile (tree->right);
1399 /*-----------------------------------------------------------------*/
1400 /* astHasPointer - return true if the ast contains any ptr variable */
1401 /*-----------------------------------------------------------------*/
1403 astHasPointer (ast * tree)
1408 if (IS_AST_LINK (tree))
1411 /* if we hit an array expression then check
1412 only the left side */
1413 if (IS_AST_OP (tree) && tree->opval.op == '[')
1414 return astHasPointer (tree->left);
1416 if (IS_AST_VALUE (tree))
1417 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1419 return astHasPointer (tree->left) ||
1420 astHasPointer (tree->right);
1424 /*-----------------------------------------------------------------*/
1425 /* astHasSymbol - return true if the ast has the given symbol */
1426 /*-----------------------------------------------------------------*/
1428 astHasSymbol (ast * tree, symbol * sym)
1430 if (!tree || IS_AST_LINK (tree))
1433 if (IS_AST_VALUE (tree))
1435 if (IS_AST_SYM_VALUE (tree))
1436 return isSymbolEqual (AST_SYMBOL (tree), sym);
1441 return astHasSymbol (tree->left, sym) ||
1442 astHasSymbol (tree->right, sym);
1445 /*-----------------------------------------------------------------*/
1446 /* astHasDeref - return true if the ast has an indirect access */
1447 /*-----------------------------------------------------------------*/
1449 astHasDeref (ast * tree)
1451 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1454 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1456 return astHasDeref (tree->left) || astHasDeref (tree->right);
1459 /*-----------------------------------------------------------------*/
1460 /* isConformingBody - the loop body has to conform to a set of rules */
1461 /* for the loop to be considered reversible read on for rules */
1462 /*-----------------------------------------------------------------*/
1464 isConformingBody (ast * pbody, symbol * sym, ast * body)
1467 /* we are going to do a pre-order traversal of the
1468 tree && check for the following conditions. (essentially
1469 a set of very shallow tests )
1470 a) the sym passed does not participate in
1471 any arithmetic operation
1472 b) There are no function calls
1473 c) all jumps are within the body
1474 d) address of loop control variable not taken
1475 e) if an assignment has a pointer on the
1476 left hand side make sure right does not have
1477 loop control variable */
1479 /* if we reach the end or a leaf then true */
1480 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1484 /* if anything else is "volatile" */
1485 if (IS_VOLATILE (TETYPE (pbody)))
1488 /* we will walk the body in a pre-order traversal for
1490 switch (pbody->opval.op)
1492 /*------------------------------------------------------------------*/
1494 return isConformingBody (pbody->right, sym, body);
1496 /*------------------------------------------------------------------*/
1501 /*------------------------------------------------------------------*/
1502 case INC_OP: /* incerement operator unary so left only */
1505 /* sure we are not sym is not modified */
1507 IS_AST_SYM_VALUE (pbody->left) &&
1508 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1512 IS_AST_SYM_VALUE (pbody->right) &&
1513 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1518 /*------------------------------------------------------------------*/
1520 case '*': /* can be unary : if right is null then unary operation */
1525 /* if right is NULL then unary operation */
1526 /*------------------------------------------------------------------*/
1527 /*----------------------------*/
1529 /*----------------------------*/
1532 if (IS_AST_SYM_VALUE (pbody->left) &&
1533 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1536 return isConformingBody (pbody->left, sym, body);
1540 if (astHasSymbol (pbody->left, sym) ||
1541 astHasSymbol (pbody->right, sym))
1546 /*------------------------------------------------------------------*/
1554 if (IS_AST_SYM_VALUE (pbody->left) &&
1555 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1558 if (IS_AST_SYM_VALUE (pbody->right) &&
1559 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1562 return isConformingBody (pbody->left, sym, body) &&
1563 isConformingBody (pbody->right, sym, body);
1570 if (IS_AST_SYM_VALUE (pbody->left) &&
1571 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1573 return isConformingBody (pbody->left, sym, body);
1575 /*------------------------------------------------------------------*/
1587 case SIZEOF: /* evaluate wihout code generation */
1589 return isConformingBody (pbody->left, sym, body) &&
1590 isConformingBody (pbody->right, sym, body);
1592 /*------------------------------------------------------------------*/
1595 /* if left has a pointer & right has loop
1596 control variable then we cannot */
1597 if (astHasPointer (pbody->left) &&
1598 astHasSymbol (pbody->right, sym))
1600 if (astHasVolatile (pbody->left))
1603 if (IS_AST_SYM_VALUE (pbody->left) &&
1604 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1607 if (astHasVolatile (pbody->left))
1610 if (astHasDeref(pbody->right)) return FALSE;
1612 return isConformingBody (pbody->left, sym, body) &&
1613 isConformingBody (pbody->right, sym, body);
1624 assert ("Parser should not have generated this\n");
1626 /*------------------------------------------------------------------*/
1627 /*----------------------------*/
1628 /* comma operator */
1629 /*----------------------------*/
1631 return isConformingBody (pbody->left, sym, body) &&
1632 isConformingBody (pbody->right, sym, body);
1634 /*------------------------------------------------------------------*/
1635 /*----------------------------*/
1637 /*----------------------------*/
1641 /*------------------------------------------------------------------*/
1642 /*----------------------------*/
1643 /* return statement */
1644 /*----------------------------*/
1649 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1654 if (astHasSymbol (pbody->left, sym))
1661 return isConformingBody (pbody->left, sym, body) &&
1662 isConformingBody (pbody->right, sym, body);
1668 /*-----------------------------------------------------------------*/
1669 /* isLoopReversible - takes a for loop as input && returns true */
1670 /* if the for loop is reversible. If yes will set the value of */
1671 /* the loop control var & init value & termination value */
1672 /*-----------------------------------------------------------------*/
1674 isLoopReversible (ast * loop, symbol ** loopCntrl,
1675 ast ** init, ast ** end)
1677 /* if option says don't do it then don't */
1678 if (optimize.noLoopReverse)
1680 /* there are several tests to determine this */
1682 /* for loop has to be of the form
1683 for ( <sym> = <const1> ;
1684 [<sym> < <const2>] ;
1685 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1687 if (!isLoopCountable (AST_FOR (loop, initExpr),
1688 AST_FOR (loop, condExpr),
1689 AST_FOR (loop, loopExpr),
1690 loopCntrl, init, end))
1693 /* now do some serious checking on the body of the loop
1696 return isConformingBody (loop->left, *loopCntrl, loop->left);
1700 /*-----------------------------------------------------------------*/
1701 /* replLoopSym - replace the loop sym by loop sym -1 */
1702 /*-----------------------------------------------------------------*/
1704 replLoopSym (ast * body, symbol * sym)
1707 if (!body || IS_AST_LINK (body))
1710 if (IS_AST_SYM_VALUE (body))
1713 if (isSymbolEqual (AST_SYMBOL (body), sym))
1717 body->opval.op = '-';
1718 body->left = newAst_VALUE (symbolVal (sym));
1719 body->right = newAst_VALUE (constVal ("1"));
1727 replLoopSym (body->left, sym);
1728 replLoopSym (body->right, sym);
1732 /*-----------------------------------------------------------------*/
1733 /* reverseLoop - do the actual loop reversal */
1734 /*-----------------------------------------------------------------*/
1736 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1740 /* create the following tree
1745 if (sym) goto for_continue ;
1748 /* put it together piece by piece */
1749 rloop = newNode (NULLOP,
1750 createIf (newAst_VALUE (symbolVal (sym)),
1752 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1755 newAst_VALUE (symbolVal (sym)),
1758 replLoopSym (loop->left, sym);
1760 rloop = newNode (NULLOP,
1762 newAst_VALUE (symbolVal (sym)),
1763 newNode ('-', end, init)),
1764 createLabel (AST_FOR (loop, continueLabel),
1768 newNode (SUB_ASSIGN,
1769 newAst_VALUE (symbolVal (sym)),
1770 newAst_VALUE (constVal ("1"))),
1773 return decorateType (rloop);
1777 //#define DEMAND_INTEGER_PROMOTION
1779 #ifdef DEMAND_INTEGER_PROMOTION
1781 /*-----------------------------------------------------------------*/
1782 /* walk a tree looking for the leaves. Add a typecast to the given */
1783 /* type to each value leaf node. */
1784 /*-----------------------------------------------------------------*/
1786 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1788 if (!node || IS_CALLOP(node))
1790 /* WTF? We should never get here. */
1794 if (!node->left && !node->right)
1796 /* We're at a leaf; if it's a value, apply the typecast */
1797 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1799 *parentPtr = decorateType (newNode (CAST,
1800 newAst_LINK (copyLinkChain (type)),
1808 pushTypeCastToLeaves (type, node->left, &(node->left));
1812 pushTypeCastToLeaves (type, node->right, &(node->right));
1819 /*-----------------------------------------------------------------*/
1820 /* decorateType - compute type for this tree also does type cheking */
1821 /* this is done bottom up, since type have to flow upwards */
1822 /* it also does constant folding, and paramater checking */
1823 /*-----------------------------------------------------------------*/
1825 decorateType (ast * tree)
1833 /* if already has type then do nothing */
1834 if (tree->decorated)
1837 tree->decorated = 1;
1839 /* print the line */
1840 /* if not block & function */
1841 if (tree->type == EX_OP &&
1842 (tree->opval.op != FUNCTION &&
1843 tree->opval.op != BLOCK &&
1844 tree->opval.op != NULLOP))
1846 filename = tree->filename;
1847 lineno = tree->lineno;
1850 /* if any child is an error | this one is an error do nothing */
1851 if (tree->isError ||
1852 (tree->left && tree->left->isError) ||
1853 (tree->right && tree->right->isError))
1856 /*------------------------------------------------------------------*/
1857 /*----------------------------*/
1858 /* leaf has been reached */
1859 /*----------------------------*/
1860 /* if this is of type value */
1861 /* just get the type */
1862 if (tree->type == EX_VALUE)
1865 if (IS_LITERAL (tree->opval.val->etype))
1868 /* if this is a character array then declare it */
1869 if (IS_ARRAY (tree->opval.val->type))
1870 tree->opval.val = stringToSymbol (tree->opval.val);
1872 /* otherwise just copy the type information */
1873 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1877 if (tree->opval.val->sym)
1879 /* if the undefined flag is set then give error message */
1880 if (tree->opval.val->sym->undefined)
1882 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1884 TTYPE (tree) = TETYPE (tree) =
1885 tree->opval.val->type = tree->opval.val->sym->type =
1886 tree->opval.val->etype = tree->opval.val->sym->etype =
1887 copyLinkChain (INTTYPE);
1892 /* if impilicit i.e. struct/union member then no type */
1893 if (tree->opval.val->sym->implicit)
1894 TTYPE (tree) = TETYPE (tree) = NULL;
1899 /* else copy the type */
1900 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1902 /* and mark it as referenced */
1903 tree->opval.val->sym->isref = 1;
1911 /* if type link for the case of cast */
1912 if (tree->type == EX_LINK)
1914 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1921 dtl = decorateType (tree->left);
1922 dtr = decorateType (tree->right);
1924 /* this is to take care of situations
1925 when the tree gets rewritten */
1926 if (dtl != tree->left)
1928 if (dtr != tree->right)
1932 /* depending on type of operator do */
1934 switch (tree->opval.op)
1936 /*------------------------------------------------------------------*/
1937 /*----------------------------*/
1939 /*----------------------------*/
1942 /* determine which is the array & which the index */
1943 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1946 ast *tempTree = tree->left;
1947 tree->left = tree->right;
1948 tree->right = tempTree;
1951 /* first check if this is a array or a pointer */
1952 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1954 werror (E_NEED_ARRAY_PTR, "[]");
1955 goto errorTreeReturn;
1958 /* check if the type of the idx */
1959 if (!IS_INTEGRAL (RTYPE (tree)))
1961 werror (E_IDX_NOT_INT);
1962 goto errorTreeReturn;
1965 /* if the left is an rvalue then error */
1968 werror (E_LVALUE_REQUIRED, "array access");
1969 goto errorTreeReturn;
1972 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1973 if (IS_PTR(LTYPE(tree))) {
1974 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1978 /*------------------------------------------------------------------*/
1979 /*----------------------------*/
1981 /*----------------------------*/
1983 /* if this is not a structure */
1984 if (!IS_STRUCT (LTYPE (tree)))
1986 werror (E_STRUCT_UNION, ".");
1987 goto errorTreeReturn;
1989 TTYPE (tree) = structElemType (LTYPE (tree),
1990 (tree->right->type == EX_VALUE ?
1991 tree->right->opval.val : NULL));
1992 TETYPE (tree) = getSpec (TTYPE (tree));
1995 /*------------------------------------------------------------------*/
1996 /*----------------------------*/
1997 /* struct/union pointer */
1998 /*----------------------------*/
2000 /* if not pointer to a structure */
2001 if (!IS_PTR (LTYPE (tree)))
2003 werror (E_PTR_REQD);
2004 goto errorTreeReturn;
2007 if (!IS_STRUCT (LTYPE (tree)->next))
2009 werror (E_STRUCT_UNION, "->");
2010 goto errorTreeReturn;
2013 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2014 (tree->right->type == EX_VALUE ?
2015 tree->right->opval.val : NULL));
2016 TETYPE (tree) = getSpec (TTYPE (tree));
2019 /*------------------------------------------------------------------*/
2020 /*----------------------------*/
2021 /* ++/-- operation */
2022 /*----------------------------*/
2023 case INC_OP: /* incerement operator unary so left only */
2026 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2027 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2028 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2029 werror (E_CODE_WRITE, "++/--");
2038 /*------------------------------------------------------------------*/
2039 /*----------------------------*/
2041 /*----------------------------*/
2042 case '&': /* can be unary */
2043 /* if right is NULL then unary operation */
2044 if (tree->right) /* not an unary operation */
2047 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2049 werror (E_BITWISE_OP);
2050 werror (W_CONTINUE, "left & right types are ");
2051 printTypeChain (LTYPE (tree), stderr);
2052 fprintf (stderr, ",");
2053 printTypeChain (RTYPE (tree), stderr);
2054 fprintf (stderr, "\n");
2055 goto errorTreeReturn;
2058 /* if they are both literal */
2059 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2061 tree->type = EX_VALUE;
2062 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2063 valFromType (RETYPE (tree)), '&');
2065 tree->right = tree->left = NULL;
2066 TETYPE (tree) = tree->opval.val->etype;
2067 TTYPE (tree) = tree->opval.val->type;
2071 /* see if this is a GETHBIT operation if yes
2074 ast *otree = optimizeGetHbit (tree);
2077 return decorateType (otree);
2081 computeType (LTYPE (tree), RTYPE (tree));
2082 TETYPE (tree) = getSpec (TTYPE (tree));
2084 LRVAL (tree) = RRVAL (tree) = 1;
2088 /*------------------------------------------------------------------*/
2089 /*----------------------------*/
2091 /*----------------------------*/
2093 p->class = DECLARATOR;
2094 /* if bit field then error */
2095 if (IS_BITVAR (tree->left->etype))
2097 werror (E_ILLEGAL_ADDR, "address of bit variable");
2098 goto errorTreeReturn;
2101 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2103 werror (E_ILLEGAL_ADDR, "address of register variable");
2104 goto errorTreeReturn;
2107 if (IS_FUNC (LTYPE (tree)))
2109 werror (E_ILLEGAL_ADDR, "address of function");
2110 goto errorTreeReturn;
2113 if (IS_LITERAL(LTYPE(tree)))
2115 werror (E_ILLEGAL_ADDR, "address of literal");
2116 goto errorTreeReturn;
2121 werror (E_LVALUE_REQUIRED, "address of");
2122 goto errorTreeReturn;
2124 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2126 DCL_TYPE (p) = CPOINTER;
2127 DCL_PTR_CONST (p) = port->mem.code_ro;
2129 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2130 DCL_TYPE (p) = FPOINTER;
2131 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2132 DCL_TYPE (p) = PPOINTER;
2133 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2134 DCL_TYPE (p) = IPOINTER;
2135 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2136 DCL_TYPE (p) = EEPPOINTER;
2138 DCL_TYPE (p) = POINTER;
2140 if (IS_AST_SYM_VALUE (tree->left))
2142 AST_SYMBOL (tree->left)->addrtaken = 1;
2143 AST_SYMBOL (tree->left)->allocreq = 1;
2146 p->next = LTYPE (tree);
2148 TETYPE (tree) = getSpec (TTYPE (tree));
2149 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2150 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2155 /*------------------------------------------------------------------*/
2156 /*----------------------------*/
2158 /*----------------------------*/
2160 /* if the rewrite succeeds then don't go any furthur */
2162 ast *wtree = optimizeRRCRLC (tree);
2164 return decorateType (wtree);
2166 /*------------------------------------------------------------------*/
2167 /*----------------------------*/
2169 /*----------------------------*/
2171 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2173 werror (E_BITWISE_OP);
2174 werror (W_CONTINUE, "left & right types are ");
2175 printTypeChain (LTYPE (tree), stderr);
2176 fprintf (stderr, ",");
2177 printTypeChain (RTYPE (tree), stderr);
2178 fprintf (stderr, "\n");
2179 goto errorTreeReturn;
2182 /* if they are both literal then */
2183 /* rewrite the tree */
2184 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2186 tree->type = EX_VALUE;
2187 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2188 valFromType (RETYPE (tree)),
2190 tree->right = tree->left = NULL;
2191 TETYPE (tree) = tree->opval.val->etype;
2192 TTYPE (tree) = tree->opval.val->type;
2195 LRVAL (tree) = RRVAL (tree) = 1;
2196 TETYPE (tree) = getSpec (TTYPE (tree) =
2197 computeType (LTYPE (tree),
2200 /*------------------------------------------------------------------*/
2201 /*----------------------------*/
2203 /*----------------------------*/
2205 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2207 werror (E_INVALID_OP, "divide");
2208 goto errorTreeReturn;
2210 /* if they are both literal then */
2211 /* rewrite the tree */
2212 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2214 tree->type = EX_VALUE;
2215 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2216 valFromType (RETYPE (tree)));
2217 tree->right = tree->left = NULL;
2218 TETYPE (tree) = getSpec (TTYPE (tree) =
2219 tree->opval.val->type);
2222 LRVAL (tree) = RRVAL (tree) = 1;
2223 TETYPE (tree) = getSpec (TTYPE (tree) =
2224 computeType (LTYPE (tree),
2228 /*------------------------------------------------------------------*/
2229 /*----------------------------*/
2231 /*----------------------------*/
2233 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2235 werror (E_BITWISE_OP);
2236 werror (W_CONTINUE, "left & right types are ");
2237 printTypeChain (LTYPE (tree), stderr);
2238 fprintf (stderr, ",");
2239 printTypeChain (RTYPE (tree), stderr);
2240 fprintf (stderr, "\n");
2241 goto errorTreeReturn;
2243 /* if they are both literal then */
2244 /* rewrite the tree */
2245 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2247 tree->type = EX_VALUE;
2248 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2249 valFromType (RETYPE (tree)));
2250 tree->right = tree->left = NULL;
2251 TETYPE (tree) = getSpec (TTYPE (tree) =
2252 tree->opval.val->type);
2255 LRVAL (tree) = RRVAL (tree) = 1;
2256 TETYPE (tree) = getSpec (TTYPE (tree) =
2257 computeType (LTYPE (tree),
2261 /*------------------------------------------------------------------*/
2262 /*----------------------------*/
2263 /* address dereference */
2264 /*----------------------------*/
2265 case '*': /* can be unary : if right is null then unary operation */
2268 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2270 werror (E_PTR_REQD);
2271 goto errorTreeReturn;
2276 werror (E_LVALUE_REQUIRED, "pointer deref");
2277 goto errorTreeReturn;
2279 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2280 LTYPE (tree)->next : NULL);
2281 TETYPE (tree) = getSpec (TTYPE (tree));
2282 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2286 /*------------------------------------------------------------------*/
2287 /*----------------------------*/
2288 /* multiplication */
2289 /*----------------------------*/
2290 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2292 werror (E_INVALID_OP, "multiplication");
2293 goto errorTreeReturn;
2296 /* if they are both literal then */
2297 /* rewrite the tree */
2298 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2300 tree->type = EX_VALUE;
2301 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2302 valFromType (RETYPE (tree)));
2303 tree->right = tree->left = NULL;
2304 TETYPE (tree) = getSpec (TTYPE (tree) =
2305 tree->opval.val->type);
2309 /* if left is a literal exchange left & right */
2310 if (IS_LITERAL (LTYPE (tree)))
2312 ast *tTree = tree->left;
2313 tree->left = tree->right;
2314 tree->right = tTree;
2317 LRVAL (tree) = RRVAL (tree) = 1;
2318 /* promote result to int if left & right are char
2319 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2320 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2321 TETYPE (tree) = getSpec (TTYPE (tree) =
2322 computeType (LTYPE (tree),
2324 SPEC_NOUN(TETYPE(tree)) = V_INT;
2326 TETYPE (tree) = getSpec (TTYPE (tree) =
2327 computeType (LTYPE (tree),
2332 /*------------------------------------------------------------------*/
2333 /*----------------------------*/
2334 /* unary '+' operator */
2335 /*----------------------------*/
2340 if (!IS_INTEGRAL (LTYPE (tree)))
2342 werror (E_UNARY_OP, '+');
2343 goto errorTreeReturn;
2346 /* if left is a literal then do it */
2347 if (IS_LITERAL (LTYPE (tree)))
2349 tree->type = EX_VALUE;
2350 tree->opval.val = valFromType (LETYPE (tree));
2352 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2356 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2360 /*------------------------------------------------------------------*/
2361 /*----------------------------*/
2363 /*----------------------------*/
2365 /* this is not a unary operation */
2366 /* if both pointers then problem */
2367 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2368 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2370 werror (E_PTR_PLUS_PTR);
2371 goto errorTreeReturn;
2374 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2375 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2377 werror (E_PLUS_INVALID, "+");
2378 goto errorTreeReturn;
2381 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2382 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2384 werror (E_PLUS_INVALID, "+");
2385 goto errorTreeReturn;
2387 /* if they are both literal then */
2388 /* rewrite the tree */
2389 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2391 tree->type = EX_VALUE;
2392 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2393 valFromType (RETYPE (tree)));
2394 tree->right = tree->left = NULL;
2395 TETYPE (tree) = getSpec (TTYPE (tree) =
2396 tree->opval.val->type);
2400 /* if the right is a pointer or left is a literal
2401 xchange left & right */
2402 if (IS_ARRAY (RTYPE (tree)) ||
2403 IS_PTR (RTYPE (tree)) ||
2404 IS_LITERAL (LTYPE (tree)))
2406 ast *tTree = tree->left;
2407 tree->left = tree->right;
2408 tree->right = tTree;
2411 LRVAL (tree) = RRVAL (tree) = 1;
2412 /* if the left is a pointer */
2413 if (IS_PTR (LTYPE (tree)))
2414 TETYPE (tree) = getSpec (TTYPE (tree) =
2417 TETYPE (tree) = getSpec (TTYPE (tree) =
2418 computeType (LTYPE (tree),
2422 /*------------------------------------------------------------------*/
2423 /*----------------------------*/
2425 /*----------------------------*/
2426 case '-': /* can be unary */
2427 /* if right is null then unary */
2431 if (!IS_ARITHMETIC (LTYPE (tree)))
2433 werror (E_UNARY_OP, tree->opval.op);
2434 goto errorTreeReturn;
2437 /* if left is a literal then do it */
2438 if (IS_LITERAL (LTYPE (tree)))
2440 tree->type = EX_VALUE;
2441 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2443 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2444 SPEC_USIGN(TETYPE(tree)) = 0;
2448 TTYPE (tree) = LTYPE (tree);
2452 /*------------------------------------------------------------------*/
2453 /*----------------------------*/
2455 /*----------------------------*/
2457 if (!(IS_PTR (LTYPE (tree)) ||
2458 IS_ARRAY (LTYPE (tree)) ||
2459 IS_ARITHMETIC (LTYPE (tree))))
2461 werror (E_PLUS_INVALID, "-");
2462 goto errorTreeReturn;
2465 if (!(IS_PTR (RTYPE (tree)) ||
2466 IS_ARRAY (RTYPE (tree)) ||
2467 IS_ARITHMETIC (RTYPE (tree))))
2469 werror (E_PLUS_INVALID, "-");
2470 goto errorTreeReturn;
2473 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2474 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2475 IS_INTEGRAL (RTYPE (tree))))
2477 werror (E_PLUS_INVALID, "-");
2478 goto errorTreeReturn;
2481 /* if they are both literal then */
2482 /* rewrite the tree */
2483 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2485 tree->type = EX_VALUE;
2486 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2487 valFromType (RETYPE (tree)));
2488 tree->right = tree->left = NULL;
2489 TETYPE (tree) = getSpec (TTYPE (tree) =
2490 tree->opval.val->type);
2494 /* if the left & right are equal then zero */
2495 if (isAstEqual (tree->left, tree->right))
2497 tree->type = EX_VALUE;
2498 tree->left = tree->right = NULL;
2499 tree->opval.val = constVal ("0");
2500 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2504 /* if both of them are pointers or arrays then */
2505 /* the result is going to be an integer */
2506 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2507 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2508 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2510 /* if only the left is a pointer */
2511 /* then result is a pointer */
2512 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2513 TETYPE (tree) = getSpec (TTYPE (tree) =
2516 TETYPE (tree) = getSpec (TTYPE (tree) =
2517 computeType (LTYPE (tree),
2519 LRVAL (tree) = RRVAL (tree) = 1;
2522 /*------------------------------------------------------------------*/
2523 /*----------------------------*/
2525 /*----------------------------*/
2527 /* can be only integral type */
2528 if (!IS_INTEGRAL (LTYPE (tree)))
2530 werror (E_UNARY_OP, tree->opval.op);
2531 goto errorTreeReturn;
2534 /* if left is a literal then do it */
2535 if (IS_LITERAL (LTYPE (tree)))
2537 tree->type = EX_VALUE;
2538 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2540 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2544 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2547 /*------------------------------------------------------------------*/
2548 /*----------------------------*/
2550 /*----------------------------*/
2552 /* can be pointer */
2553 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2554 !IS_PTR (LTYPE (tree)) &&
2555 !IS_ARRAY (LTYPE (tree)))
2557 werror (E_UNARY_OP, tree->opval.op);
2558 goto errorTreeReturn;
2561 /* if left is a literal then do it */
2562 if (IS_LITERAL (LTYPE (tree)))
2564 tree->type = EX_VALUE;
2565 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2567 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2571 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2574 /*------------------------------------------------------------------*/
2575 /*----------------------------*/
2577 /*----------------------------*/
2580 TTYPE (tree) = LTYPE (tree);
2581 TETYPE (tree) = LETYPE (tree);
2585 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2590 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2592 werror (E_SHIFT_OP_INVALID);
2593 werror (W_CONTINUE, "left & right types are ");
2594 printTypeChain (LTYPE (tree), stderr);
2595 fprintf (stderr, ",");
2596 printTypeChain (RTYPE (tree), stderr);
2597 fprintf (stderr, "\n");
2598 goto errorTreeReturn;
2601 /* if they are both literal then */
2602 /* rewrite the tree */
2603 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2605 tree->type = EX_VALUE;
2606 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2607 valFromType (RETYPE (tree)),
2608 (tree->opval.op == LEFT_OP ? 1 : 0));
2609 tree->right = tree->left = NULL;
2610 TETYPE (tree) = getSpec (TTYPE (tree) =
2611 tree->opval.val->type);
2614 /* if only the right side is a literal & we are
2615 shifting more than size of the left operand then zero */
2616 if (IS_LITERAL (RTYPE (tree)) &&
2617 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2618 (getSize (LTYPE (tree)) * 8))
2620 werror (W_SHIFT_CHANGED,
2621 (tree->opval.op == LEFT_OP ? "left" : "right"));
2622 tree->type = EX_VALUE;
2623 tree->left = tree->right = NULL;
2624 tree->opval.val = constVal ("0");
2625 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2628 LRVAL (tree) = RRVAL (tree) = 1;
2629 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2631 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2635 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2639 /*------------------------------------------------------------------*/
2640 /*----------------------------*/
2642 /*----------------------------*/
2643 case CAST: /* change the type */
2644 /* cannot cast to an aggregate type */
2645 if (IS_AGGREGATE (LTYPE (tree)))
2647 werror (E_CAST_ILLEGAL);
2648 goto errorTreeReturn;
2651 /* make sure the type is complete and sane */
2652 checkTypeSanity(LETYPE(tree), "(cast)");
2655 /* if the right is a literal replace the tree */
2656 if (IS_LITERAL (RETYPE (tree))) {
2657 if (!IS_PTR (LTYPE (tree))) {
2658 tree->type = EX_VALUE;
2660 valCastLiteral (LTYPE (tree),
2661 floatFromVal (valFromType (RETYPE (tree))));
2664 TTYPE (tree) = tree->opval.val->type;
2665 tree->values.literalFromCast = 1;
2666 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2667 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2668 sym_link *rest = LTYPE(tree)->next;
2669 werror(W_LITERAL_GENERIC);
2670 TTYPE(tree) = newLink();
2671 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2672 TTYPE(tree)->next = rest;
2673 tree->left->opval.lnk = TTYPE(tree);
2676 TTYPE (tree) = LTYPE (tree);
2680 TTYPE (tree) = LTYPE (tree);
2684 /* if pointer to struct then check names */
2685 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2686 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2687 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2688 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2690 /* if the right is a literal replace the tree */
2691 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2692 tree->type = EX_VALUE;
2694 valCastLiteral (LTYPE (tree),
2695 floatFromVal (valFromType (RETYPE (tree))));
2698 TTYPE (tree) = tree->opval.val->type;
2699 tree->values.literalFromCast = 1;
2701 TTYPE (tree) = LTYPE (tree);
2705 TETYPE (tree) = getSpec (TTYPE (tree));
2709 /*------------------------------------------------------------------*/
2710 /*----------------------------*/
2711 /* logical &&, || */
2712 /*----------------------------*/
2715 /* each must me arithmetic type or be a pointer */
2716 if (!IS_PTR (LTYPE (tree)) &&
2717 !IS_ARRAY (LTYPE (tree)) &&
2718 !IS_INTEGRAL (LTYPE (tree)))
2720 werror (E_COMPARE_OP);
2721 goto errorTreeReturn;
2724 if (!IS_PTR (RTYPE (tree)) &&
2725 !IS_ARRAY (RTYPE (tree)) &&
2726 !IS_INTEGRAL (RTYPE (tree)))
2728 werror (E_COMPARE_OP);
2729 goto errorTreeReturn;
2731 /* if they are both literal then */
2732 /* rewrite the tree */
2733 if (IS_LITERAL (RTYPE (tree)) &&
2734 IS_LITERAL (LTYPE (tree)))
2736 tree->type = EX_VALUE;
2737 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2738 valFromType (RETYPE (tree)),
2740 tree->right = tree->left = NULL;
2741 TETYPE (tree) = getSpec (TTYPE (tree) =
2742 tree->opval.val->type);
2745 LRVAL (tree) = RRVAL (tree) = 1;
2746 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2749 /*------------------------------------------------------------------*/
2750 /*----------------------------*/
2751 /* comparison operators */
2752 /*----------------------------*/
2760 ast *lt = optimizeCompare (tree);
2766 /* if they are pointers they must be castable */
2767 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2769 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2771 werror (E_COMPARE_OP);
2772 fprintf (stderr, "comparing type ");
2773 printTypeChain (LTYPE (tree), stderr);
2774 fprintf (stderr, "to type ");
2775 printTypeChain (RTYPE (tree), stderr);
2776 fprintf (stderr, "\n");
2777 goto errorTreeReturn;
2780 /* else they should be promotable to one another */
2783 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2784 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2786 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2788 werror (E_COMPARE_OP);
2789 fprintf (stderr, "comparing type ");
2790 printTypeChain (LTYPE (tree), stderr);
2791 fprintf (stderr, "to type ");
2792 printTypeChain (RTYPE (tree), stderr);
2793 fprintf (stderr, "\n");
2794 goto errorTreeReturn;
2798 /* if they are both literal then */
2799 /* rewrite the tree */
2800 if (IS_LITERAL (RTYPE (tree)) &&
2801 IS_LITERAL (LTYPE (tree)))
2803 tree->type = EX_VALUE;
2804 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2805 valFromType (RETYPE (tree)),
2807 tree->right = tree->left = NULL;
2808 TETYPE (tree) = getSpec (TTYPE (tree) =
2809 tree->opval.val->type);
2812 LRVAL (tree) = RRVAL (tree) = 1;
2813 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2816 /*------------------------------------------------------------------*/
2817 /*----------------------------*/
2819 /*----------------------------*/
2820 case SIZEOF: /* evaluate wihout code generation */
2821 /* change the type to a integer */
2822 tree->type = EX_VALUE;
2823 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2824 tree->opval.val = constVal (buffer);
2825 tree->right = tree->left = NULL;
2826 TETYPE (tree) = getSpec (TTYPE (tree) =
2827 tree->opval.val->type);
2830 /*------------------------------------------------------------------*/
2831 /*----------------------------*/
2832 /* conditional operator '?' */
2833 /*----------------------------*/
2835 /* the type is value of the colon operator (on the right) */
2836 assert(IS_COLON_OP(tree->right));
2837 /* if already known then replace the tree : optimizer will do it
2838 but faster to do it here */
2839 if (IS_LITERAL (LTYPE(tree))) {
2840 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2841 return tree->right->left ;
2843 return tree->right->right ;
2846 TTYPE (tree) = RTYPE(tree);
2847 TETYPE (tree) = getSpec (TTYPE (tree));
2852 /* if they don't match we have a problem */
2853 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2855 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2856 goto errorTreeReturn;
2859 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2860 TETYPE (tree) = getSpec (TTYPE (tree));
2864 /*------------------------------------------------------------------*/
2865 /*----------------------------*/
2866 /* assignment operators */
2867 /*----------------------------*/
2870 /* for these it must be both must be integral */
2871 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2872 !IS_ARITHMETIC (RTYPE (tree)))
2874 werror (E_OPS_INTEGRAL);
2875 goto errorTreeReturn;
2878 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2880 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2881 werror (E_CODE_WRITE, " ");
2885 werror (E_LVALUE_REQUIRED, "*= or /=");
2886 goto errorTreeReturn;
2897 /* for these it must be both must be integral */
2898 if (!IS_INTEGRAL (LTYPE (tree)) ||
2899 !IS_INTEGRAL (RTYPE (tree)))
2901 werror (E_OPS_INTEGRAL);
2902 goto errorTreeReturn;
2905 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2907 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2908 werror (E_CODE_WRITE, " ");
2912 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2913 goto errorTreeReturn;
2919 /*------------------------------------------------------------------*/
2920 /*----------------------------*/
2922 /*----------------------------*/
2924 if (!(IS_PTR (LTYPE (tree)) ||
2925 IS_ARITHMETIC (LTYPE (tree))))
2927 werror (E_PLUS_INVALID, "-=");
2928 goto errorTreeReturn;
2931 if (!(IS_PTR (RTYPE (tree)) ||
2932 IS_ARITHMETIC (RTYPE (tree))))
2934 werror (E_PLUS_INVALID, "-=");
2935 goto errorTreeReturn;
2938 TETYPE (tree) = getSpec (TTYPE (tree) =
2939 computeType (LTYPE (tree),
2942 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2943 werror (E_CODE_WRITE, " ");
2947 werror (E_LVALUE_REQUIRED, "-=");
2948 goto errorTreeReturn;
2954 /*------------------------------------------------------------------*/
2955 /*----------------------------*/
2957 /*----------------------------*/
2959 /* this is not a unary operation */
2960 /* if both pointers then problem */
2961 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2963 werror (E_PTR_PLUS_PTR);
2964 goto errorTreeReturn;
2967 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2969 werror (E_PLUS_INVALID, "+=");
2970 goto errorTreeReturn;
2973 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2975 werror (E_PLUS_INVALID, "+=");
2976 goto errorTreeReturn;
2979 TETYPE (tree) = getSpec (TTYPE (tree) =
2980 computeType (LTYPE (tree),
2983 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2984 werror (E_CODE_WRITE, " ");
2988 werror (E_LVALUE_REQUIRED, "+=");
2989 goto errorTreeReturn;
2992 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2993 tree->opval.op = '=';
2997 /*------------------------------------------------------------------*/
2998 /*----------------------------*/
2999 /* straight assignemnt */
3000 /*----------------------------*/
3002 /* cannot be an aggregate */
3003 if (IS_AGGREGATE (LTYPE (tree)))
3005 werror (E_AGGR_ASSIGN);
3006 goto errorTreeReturn;
3009 /* they should either match or be castable */
3010 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3012 werror (E_TYPE_MISMATCH, "assignment", " ");
3013 fprintf (stderr, "type --> '");
3014 printTypeChain (RTYPE (tree), stderr);
3015 fprintf (stderr, "' ");
3016 fprintf (stderr, "assigned to type --> '");
3017 printTypeChain (LTYPE (tree), stderr);
3018 fprintf (stderr, "'\n");
3019 goto errorTreeReturn;
3022 /* if the left side of the tree is of type void
3023 then report error */
3024 if (IS_VOID (LTYPE (tree)))
3026 werror (E_CAST_ZERO);
3027 printFromToType(RTYPE(tree), LTYPE(tree));
3030 TETYPE (tree) = getSpec (TTYPE (tree) =
3034 if (!tree->initMode ) {
3035 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3036 werror (E_CODE_WRITE, " ");
3040 werror (E_LVALUE_REQUIRED, "=");
3041 goto errorTreeReturn;
3046 /*------------------------------------------------------------------*/
3047 /*----------------------------*/
3048 /* comma operator */
3049 /*----------------------------*/
3051 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3054 /*------------------------------------------------------------------*/
3055 /*----------------------------*/
3057 /*----------------------------*/
3061 if (processParms (tree->left,
3062 FUNC_ARGS(tree->left->ftype),
3063 tree->right, &parmNumber, TRUE)) {
3064 goto errorTreeReturn;
3067 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3069 //FUNC_ARGS(tree->left->ftype) =
3070 //reverseVal (FUNC_ARGS(tree->left->ftype));
3071 reverseParms (tree->right);
3074 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3077 /*------------------------------------------------------------------*/
3078 /*----------------------------*/
3079 /* return statement */
3080 /*----------------------------*/
3085 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3087 werror (W_RETURN_MISMATCH);
3088 printFromToType (RTYPE(tree), currFunc->type->next);
3089 goto errorTreeReturn;
3092 if (IS_VOID (currFunc->type->next)
3094 !IS_VOID (RTYPE (tree)))
3096 werror (E_FUNC_VOID);
3097 goto errorTreeReturn;
3100 /* if there is going to be a casing required then add it */
3101 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3104 decorateType (newNode (CAST,
3105 newAst_LINK (copyLinkChain (currFunc->type->next)),
3114 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3116 werror (E_VOID_FUNC, currFunc->name);
3117 goto errorTreeReturn;
3120 TTYPE (tree) = TETYPE (tree) = NULL;
3123 /*------------------------------------------------------------------*/
3124 /*----------------------------*/
3125 /* switch statement */
3126 /*----------------------------*/
3128 /* the switch value must be an integer */
3129 if (!IS_INTEGRAL (LTYPE (tree)))
3131 werror (E_SWITCH_NON_INTEGER);
3132 goto errorTreeReturn;
3135 TTYPE (tree) = TETYPE (tree) = NULL;
3138 /*------------------------------------------------------------------*/
3139 /*----------------------------*/
3141 /*----------------------------*/
3143 tree->left = backPatchLabels (tree->left,
3146 TTYPE (tree) = TETYPE (tree) = NULL;
3149 /*------------------------------------------------------------------*/
3150 /*----------------------------*/
3152 /*----------------------------*/
3155 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3156 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3157 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3159 /* if the for loop is reversible then
3160 reverse it otherwise do what we normally
3166 if (isLoopReversible (tree, &sym, &init, &end))
3167 return reverseLoop (tree, sym, init, end);
3169 return decorateType (createFor (AST_FOR (tree, trueLabel),
3170 AST_FOR (tree, continueLabel),
3171 AST_FOR (tree, falseLabel),
3172 AST_FOR (tree, condLabel),
3173 AST_FOR (tree, initExpr),
3174 AST_FOR (tree, condExpr),
3175 AST_FOR (tree, loopExpr),
3179 TTYPE (tree) = TETYPE (tree) = NULL;
3183 /* some error found this tree will be killed */
3185 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3186 tree->opval.op = NULLOP;
3192 /*-----------------------------------------------------------------*/
3193 /* sizeofOp - processes size of operation */
3194 /*-----------------------------------------------------------------*/
3196 sizeofOp (sym_link * type)
3200 /* make sure the type is complete and sane */
3201 checkTypeSanity(type, "(sizeof)");
3203 /* get the size and convert it to character */
3204 sprintf (buff, "%d", getSize (type));
3206 /* now convert into value */
3207 return constVal (buff);
3211 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3212 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3213 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3214 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3215 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3216 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3217 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3219 /*-----------------------------------------------------------------*/
3220 /* backPatchLabels - change and or not operators to flow control */
3221 /*-----------------------------------------------------------------*/
3223 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3229 if (!(IS_ANDORNOT (tree)))
3232 /* if this an and */
3235 static int localLbl = 0;
3238 sprintf (buffer, "_and_%d", localLbl++);
3239 localLabel = newSymbol (buffer, NestLevel);
3241 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3243 /* if left is already a IFX then just change the if true label in that */
3244 if (!IS_IFX (tree->left))
3245 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3247 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3248 /* right is a IFX then just join */
3249 if (IS_IFX (tree->right))
3250 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3252 tree->right = createLabel (localLabel, tree->right);
3253 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3255 return newNode (NULLOP, tree->left, tree->right);
3258 /* if this is an or operation */
3261 static int localLbl = 0;
3264 sprintf (buffer, "_or_%d", localLbl++);
3265 localLabel = newSymbol (buffer, NestLevel);
3267 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3269 /* if left is already a IFX then just change the if true label in that */
3270 if (!IS_IFX (tree->left))
3271 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3273 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3274 /* right is a IFX then just join */
3275 if (IS_IFX (tree->right))
3276 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3278 tree->right = createLabel (localLabel, tree->right);
3279 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3281 return newNode (NULLOP, tree->left, tree->right);
3287 int wasnot = IS_NOT (tree->left);
3288 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3290 /* if the left is already a IFX */
3291 if (!IS_IFX (tree->left))
3292 tree->left = newNode (IFX, tree->left, NULL);
3296 tree->left->trueLabel = trueLabel;
3297 tree->left->falseLabel = falseLabel;
3301 tree->left->trueLabel = falseLabel;
3302 tree->left->falseLabel = trueLabel;
3309 tree->trueLabel = trueLabel;
3310 tree->falseLabel = falseLabel;
3317 /*-----------------------------------------------------------------*/
3318 /* createBlock - create expression tree for block */
3319 /*-----------------------------------------------------------------*/
3321 createBlock (symbol * decl, ast * body)
3325 /* if the block has nothing */
3329 ex = newNode (BLOCK, NULL, body);
3330 ex->values.sym = decl;
3332 ex->right = ex->right;
3338 /*-----------------------------------------------------------------*/
3339 /* createLabel - creates the expression tree for labels */
3340 /*-----------------------------------------------------------------*/
3342 createLabel (symbol * label, ast * stmnt)
3345 char name[SDCC_NAME_MAX + 1];
3348 /* must create fresh symbol if the symbol name */
3349 /* exists in the symbol table, since there can */
3350 /* be a variable with the same name as the labl */
3351 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3352 (csym->level == label->level))
3353 label = newSymbol (label->name, label->level);
3355 /* change the name before putting it in add _ */
3356 sprintf (name, "%s", label->name);
3358 /* put the label in the LabelSymbol table */
3359 /* but first check if a label of the same */
3361 if ((csym = findSym (LabelTab, NULL, name)))
3362 werror (E_DUPLICATE_LABEL, label->name);
3364 addSym (LabelTab, label, name, label->level, 0, 0);
3367 label->key = labelKey++;
3368 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3374 /*-----------------------------------------------------------------*/
3375 /* createCase - generates the parsetree for a case statement */
3376 /*-----------------------------------------------------------------*/
3378 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3380 char caseLbl[SDCC_NAME_MAX + 1];
3384 /* if the switch statement does not exist */
3385 /* then case is out of context */
3388 werror (E_CASE_CONTEXT);
3392 caseVal = decorateType (resolveSymbols (caseVal));
3393 /* if not a constant then error */
3394 if (!IS_LITERAL (caseVal->ftype))
3396 werror (E_CASE_CONSTANT);
3400 /* if not a integer than error */
3401 if (!IS_INTEGRAL (caseVal->ftype))
3403 werror (E_CASE_NON_INTEGER);
3407 /* find the end of the switch values chain */
3408 if (!(val = swStat->values.switchVals.swVals))
3409 swStat->values.switchVals.swVals = caseVal->opval.val;
3412 /* also order the cases according to value */
3414 int cVal = (int) floatFromVal (caseVal->opval.val);
3415 while (val && (int) floatFromVal (val) < cVal)
3421 /* if we reached the end then */
3424 pval->next = caseVal->opval.val;
3428 /* we found a value greater than */
3429 /* the current value we must add this */
3430 /* before the value */
3431 caseVal->opval.val->next = val;
3433 /* if this was the first in chain */
3434 if (swStat->values.switchVals.swVals == val)
3435 swStat->values.switchVals.swVals =
3438 pval->next = caseVal->opval.val;
3443 /* create the case label */
3444 sprintf (caseLbl, "_case_%d_%d",
3445 swStat->values.switchVals.swNum,
3446 (int) floatFromVal (caseVal->opval.val));
3448 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3453 /*-----------------------------------------------------------------*/
3454 /* createDefault - creates the parse tree for the default statement */
3455 /*-----------------------------------------------------------------*/
3457 createDefault (ast * swStat, ast * stmnt)
3459 char defLbl[SDCC_NAME_MAX + 1];
3461 /* if the switch statement does not exist */
3462 /* then case is out of context */
3465 werror (E_CASE_CONTEXT);
3469 /* turn on the default flag */
3470 swStat->values.switchVals.swDefault = 1;
3472 /* create the label */
3473 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3474 return createLabel (newSymbol (defLbl, 0), stmnt);
3477 /*-----------------------------------------------------------------*/
3478 /* createIf - creates the parsetree for the if statement */
3479 /*-----------------------------------------------------------------*/
3481 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3483 static int Lblnum = 0;
3485 symbol *ifTrue, *ifFalse, *ifEnd;
3487 /* if neither exists */
3488 if (!elseBody && !ifBody) {
3489 // if there are no side effects (i++, j() etc)
3490 if (!hasSEFcalls(condAst)) {
3495 /* create the labels */
3496 sprintf (buffer, "_iffalse_%d", Lblnum);
3497 ifFalse = newSymbol (buffer, NestLevel);
3498 /* if no else body then end == false */
3503 sprintf (buffer, "_ifend_%d", Lblnum);
3504 ifEnd = newSymbol (buffer, NestLevel);
3507 sprintf (buffer, "_iftrue_%d", Lblnum);
3508 ifTrue = newSymbol (buffer, NestLevel);
3512 /* attach the ifTrue label to the top of it body */
3513 ifBody = createLabel (ifTrue, ifBody);
3514 /* attach a goto end to the ifBody if else is present */
3517 ifBody = newNode (NULLOP, ifBody,
3519 newAst_VALUE (symbolVal (ifEnd)),
3521 /* put the elseLabel on the else body */
3522 elseBody = createLabel (ifFalse, elseBody);
3523 /* out the end at the end of the body */
3524 elseBody = newNode (NULLOP,
3526 createLabel (ifEnd, NULL));
3530 ifBody = newNode (NULLOP, ifBody,
3531 createLabel (ifFalse, NULL));
3533 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3534 if (IS_IFX (condAst))
3537 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3539 return newNode (NULLOP, ifTree,
3540 newNode (NULLOP, ifBody, elseBody));
3544 /*-----------------------------------------------------------------*/
3545 /* createDo - creates parse tree for do */
3548 /* _docontinue_n: */
3549 /* condition_expression +-> trueLabel -> _dobody_n */
3551 /* +-> falseLabel-> _dobreak_n */
3553 /*-----------------------------------------------------------------*/
3555 createDo (symbol * trueLabel, symbol * continueLabel,
3556 symbol * falseLabel, ast * condAst, ast * doBody)
3561 /* if the body does not exist then it is simple */
3564 condAst = backPatchLabels (condAst, continueLabel, NULL);
3565 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3566 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3567 doTree->trueLabel = continueLabel;
3568 doTree->falseLabel = NULL;
3572 /* otherwise we have a body */
3573 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3575 /* attach the body label to the top */
3576 doBody = createLabel (trueLabel, doBody);
3577 /* attach the continue label to end of body */
3578 doBody = newNode (NULLOP, doBody,
3579 createLabel (continueLabel, NULL));
3581 /* now put the break label at the end */
3582 if (IS_IFX (condAst))
3585 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3587 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3589 /* putting it together */
3590 return newNode (NULLOP, doBody, doTree);
3593 /*-----------------------------------------------------------------*/
3594 /* createFor - creates parse tree for 'for' statement */
3597 /* condExpr +-> trueLabel -> _forbody_n */
3599 /* +-> falseLabel-> _forbreak_n */
3602 /* _forcontinue_n: */
3604 /* goto _forcond_n ; */
3606 /*-----------------------------------------------------------------*/
3608 createFor (symbol * trueLabel, symbol * continueLabel,
3609 symbol * falseLabel, symbol * condLabel,
3610 ast * initExpr, ast * condExpr, ast * loopExpr,
3615 /* if loopexpression not present then we can generate it */
3616 /* the same way as a while */
3618 return newNode (NULLOP, initExpr,
3619 createWhile (trueLabel, continueLabel,
3620 falseLabel, condExpr, forBody));
3621 /* vanilla for statement */
3622 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3624 if (condExpr && !IS_IFX (condExpr))
3625 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3628 /* attach condition label to condition */
3629 condExpr = createLabel (condLabel, condExpr);
3631 /* attach body label to body */
3632 forBody = createLabel (trueLabel, forBody);
3634 /* attach continue to forLoop expression & attach */
3635 /* goto the forcond @ and of loopExpression */
3636 loopExpr = createLabel (continueLabel,
3640 newAst_VALUE (symbolVal (condLabel)),
3642 /* now start putting them together */
3643 forTree = newNode (NULLOP, initExpr, condExpr);
3644 forTree = newNode (NULLOP, forTree, forBody);
3645 forTree = newNode (NULLOP, forTree, loopExpr);
3646 /* finally add the break label */
3647 forTree = newNode (NULLOP, forTree,
3648 createLabel (falseLabel, NULL));
3652 /*-----------------------------------------------------------------*/
3653 /* createWhile - creates parse tree for while statement */
3654 /* the while statement will be created as follows */
3656 /* _while_continue_n: */
3657 /* condition_expression +-> trueLabel -> _while_boby_n */
3659 /* +-> falseLabel -> _while_break_n */
3660 /* _while_body_n: */
3662 /* goto _while_continue_n */
3663 /* _while_break_n: */
3664 /*-----------------------------------------------------------------*/
3666 createWhile (symbol * trueLabel, symbol * continueLabel,
3667 symbol * falseLabel, ast * condExpr, ast * whileBody)
3671 /* put the continue label */
3672 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3673 condExpr = createLabel (continueLabel, condExpr);
3674 condExpr->lineno = 0;
3676 /* put the body label in front of the body */
3677 whileBody = createLabel (trueLabel, whileBody);
3678 whileBody->lineno = 0;
3679 /* put a jump to continue at the end of the body */
3680 /* and put break label at the end of the body */
3681 whileBody = newNode (NULLOP,
3684 newAst_VALUE (symbolVal (continueLabel)),
3685 createLabel (falseLabel, NULL)));
3687 /* put it all together */
3688 if (IS_IFX (condExpr))
3689 whileTree = condExpr;
3692 whileTree = newNode (IFX, condExpr, NULL);
3693 /* put the true & false labels in place */
3694 whileTree->trueLabel = trueLabel;
3695 whileTree->falseLabel = falseLabel;
3698 return newNode (NULLOP, whileTree, whileBody);
3701 /*-----------------------------------------------------------------*/
3702 /* optimizeGetHbit - get highest order bit of the expression */
3703 /*-----------------------------------------------------------------*/
3705 optimizeGetHbit (ast * tree)
3708 /* if this is not a bit and */
3709 if (!IS_BITAND (tree))
3712 /* will look for tree of the form
3713 ( expr >> ((sizeof expr) -1) ) & 1 */
3714 if (!IS_AST_LIT_VALUE (tree->right))
3717 if (AST_LIT_VALUE (tree->right) != 1)
3720 if (!IS_RIGHT_OP (tree->left))
3723 if (!IS_AST_LIT_VALUE (tree->left->right))
3726 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3727 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3730 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3734 /*-----------------------------------------------------------------*/
3735 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3736 /*-----------------------------------------------------------------*/
3738 optimizeRRCRLC (ast * root)
3740 /* will look for trees of the form
3741 (?expr << 1) | (?expr >> 7) or
3742 (?expr >> 7) | (?expr << 1) will make that
3743 into a RLC : operation ..
3745 (?expr >> 1) | (?expr << 7) or
3746 (?expr << 7) | (?expr >> 1) will make that
3747 into a RRC operation
3748 note : by 7 I mean (number of bits required to hold the
3750 /* if the root operations is not a | operation the not */
3751 if (!IS_BITOR (root))
3754 /* I have to think of a better way to match patterns this sucks */
3755 /* that aside let start looking for the first case : I use a the
3756 negative check a lot to improve the efficiency */
3757 /* (?expr << 1) | (?expr >> 7) */
3758 if (IS_LEFT_OP (root->left) &&
3759 IS_RIGHT_OP (root->right))
3762 if (!SPEC_USIGN (TETYPE (root->left->left)))
3765 if (!IS_AST_LIT_VALUE (root->left->right) ||
3766 !IS_AST_LIT_VALUE (root->right->right))
3769 /* make sure it is the same expression */
3770 if (!isAstEqual (root->left->left,
3774 if (AST_LIT_VALUE (root->left->right) != 1)
3777 if (AST_LIT_VALUE (root->right->right) !=
3778 (getSize (TTYPE (root->left->left)) * 8 - 1))
3781 /* whew got the first case : create the AST */
3782 return newNode (RLC, root->left->left, NULL);
3786 /* check for second case */
3787 /* (?expr >> 7) | (?expr << 1) */
3788 if (IS_LEFT_OP (root->right) &&
3789 IS_RIGHT_OP (root->left))
3792 if (!SPEC_USIGN (TETYPE (root->left->left)))
3795 if (!IS_AST_LIT_VALUE (root->left->right) ||
3796 !IS_AST_LIT_VALUE (root->right->right))
3799 /* make sure it is the same symbol */
3800 if (!isAstEqual (root->left->left,
3804 if (AST_LIT_VALUE (root->right->right) != 1)
3807 if (AST_LIT_VALUE (root->left->right) !=
3808 (getSize (TTYPE (root->left->left)) * 8 - 1))
3811 /* whew got the first case : create the AST */
3812 return newNode (RLC, root->left->left, NULL);
3817 /* third case for RRC */
3818 /* (?symbol >> 1) | (?symbol << 7) */
3819 if (IS_LEFT_OP (root->right) &&
3820 IS_RIGHT_OP (root->left))
3823 if (!SPEC_USIGN (TETYPE (root->left->left)))
3826 if (!IS_AST_LIT_VALUE (root->left->right) ||
3827 !IS_AST_LIT_VALUE (root->right->right))
3830 /* make sure it is the same symbol */
3831 if (!isAstEqual (root->left->left,
3835 if (AST_LIT_VALUE (root->left->right) != 1)
3838 if (AST_LIT_VALUE (root->right->right) !=
3839 (getSize (TTYPE (root->left->left)) * 8 - 1))
3842 /* whew got the first case : create the AST */
3843 return newNode (RRC, root->left->left, NULL);
3847 /* fourth and last case for now */
3848 /* (?symbol << 7) | (?symbol >> 1) */
3849 if (IS_RIGHT_OP (root->right) &&
3850 IS_LEFT_OP (root->left))
3853 if (!SPEC_USIGN (TETYPE (root->left->left)))
3856 if (!IS_AST_LIT_VALUE (root->left->right) ||
3857 !IS_AST_LIT_VALUE (root->right->right))
3860 /* make sure it is the same symbol */
3861 if (!isAstEqual (root->left->left,
3865 if (AST_LIT_VALUE (root->right->right) != 1)
3868 if (AST_LIT_VALUE (root->left->right) !=
3869 (getSize (TTYPE (root->left->left)) * 8 - 1))
3872 /* whew got the first case : create the AST */
3873 return newNode (RRC, root->left->left, NULL);
3877 /* not found return root */
3881 /*-----------------------------------------------------------------*/
3882 /* optimizeCompare - otimizes compares for bit variables */
3883 /*-----------------------------------------------------------------*/
3885 optimizeCompare (ast * root)
3887 ast *optExpr = NULL;
3890 unsigned int litValue;
3892 /* if nothing then return nothing */
3896 /* if not a compare op then do leaves */
3897 if (!IS_COMPARE_OP (root))
3899 root->left = optimizeCompare (root->left);
3900 root->right = optimizeCompare (root->right);
3904 /* if left & right are the same then depending
3905 of the operation do */
3906 if (isAstEqual (root->left, root->right))
3908 switch (root->opval.op)
3913 optExpr = newAst_VALUE (constVal ("0"));
3918 optExpr = newAst_VALUE (constVal ("1"));
3922 return decorateType (optExpr);
3925 vleft = (root->left->type == EX_VALUE ?
3926 root->left->opval.val : NULL);
3928 vright = (root->right->type == EX_VALUE ?
3929 root->right->opval.val : NULL);
3931 /* if left is a BITVAR in BITSPACE */
3932 /* and right is a LITERAL then opt- */
3933 /* imize else do nothing */
3934 if (vleft && vright &&
3935 IS_BITVAR (vleft->etype) &&
3936 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3937 IS_LITERAL (vright->etype))
3940 /* if right side > 1 then comparison may never succeed */
3941 if ((litValue = (int) floatFromVal (vright)) > 1)
3943 werror (W_BAD_COMPARE);
3949 switch (root->opval.op)
3951 case '>': /* bit value greater than 1 cannot be */
3952 werror (W_BAD_COMPARE);
3956 case '<': /* bit value < 1 means 0 */
3958 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3961 case LE_OP: /* bit value <= 1 means no check */
3962 optExpr = newAst_VALUE (vright);
3965 case GE_OP: /* bit value >= 1 means only check for = */
3967 optExpr = newAst_VALUE (vleft);
3972 { /* literal is zero */
3973 switch (root->opval.op)
3975 case '<': /* bit value < 0 cannot be */
3976 werror (W_BAD_COMPARE);
3980 case '>': /* bit value > 0 means 1 */
3982 optExpr = newAst_VALUE (vleft);
3985 case LE_OP: /* bit value <= 0 means no check */
3986 case GE_OP: /* bit value >= 0 means no check */
3987 werror (W_BAD_COMPARE);
3991 case EQ_OP: /* bit == 0 means ! of bit */
3992 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3996 return decorateType (resolveSymbols (optExpr));
3997 } /* end-of-if of BITVAR */
4002 /*-----------------------------------------------------------------*/
4003 /* addSymToBlock : adds the symbol to the first block we find */
4004 /*-----------------------------------------------------------------*/
4006 addSymToBlock (symbol * sym, ast * tree)
4008 /* reached end of tree or a leaf */
4009 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4013 if (IS_AST_OP (tree) &&
4014 tree->opval.op == BLOCK)
4017 symbol *lsym = copySymbol (sym);
4019 lsym->next = AST_VALUES (tree, sym);
4020 AST_VALUES (tree, sym) = lsym;
4024 addSymToBlock (sym, tree->left);
4025 addSymToBlock (sym, tree->right);
4028 /*-----------------------------------------------------------------*/
4029 /* processRegParms - do processing for register parameters */
4030 /*-----------------------------------------------------------------*/
4032 processRegParms (value * args, ast * body)
4036 if (IS_REGPARM (args->etype))
4037 addSymToBlock (args->sym, body);
4042 /*-----------------------------------------------------------------*/
4043 /* resetParmKey - resets the operandkeys for the symbols */
4044 /*-----------------------------------------------------------------*/
4045 DEFSETFUNC (resetParmKey)
4056 /*-----------------------------------------------------------------*/
4057 /* createFunction - This is the key node that calls the iCode for */
4058 /* generating the code for a function. Note code */
4059 /* is generated function by function, later when */
4060 /* add inter-procedural analysis this will change */
4061 /*-----------------------------------------------------------------*/
4063 createFunction (symbol * name, ast * body)
4069 iCode *piCode = NULL;
4071 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4072 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4074 /* if check function return 0 then some problem */
4075 if (checkFunction (name, NULL) == 0)
4078 /* create a dummy block if none exists */
4080 body = newNode (BLOCK, NULL, NULL);
4084 /* check if the function name already in the symbol table */
4085 if ((csym = findSym (SymbolTab, NULL, name->name)))
4088 /* special case for compiler defined functions
4089 we need to add the name to the publics list : this
4090 actually means we are now compiling the compiler
4094 addSet (&publics, name);
4100 allocVariables (name);
4102 name->lastLine = yylineno;
4105 #if 0 // jwk: this is now done in addDecl()
4106 processFuncArgs (currFunc);
4109 /* set the stack pointer */
4110 /* PENDING: check this for the mcs51 */
4111 stackPtr = -port->stack.direction * port->stack.call_overhead;
4112 if (IFFUNC_ISISR (name->type))
4113 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4114 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4115 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4117 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4119 fetype = getSpec (name->type); /* get the specifier for the function */
4120 /* if this is a reentrant function then */
4121 if (IFFUNC_ISREENT (name->type))
4124 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4126 /* do processing for parameters that are passed in registers */
4127 processRegParms (FUNC_ARGS(name->type), body);
4129 /* set the stack pointer */
4133 /* allocate & autoinit the block variables */
4134 processBlockVars (body, &stack, ALLOCATE);
4136 /* save the stack information */
4137 if (options.useXstack)
4138 name->xstack = SPEC_STAK (fetype) = stack;
4140 name->stack = SPEC_STAK (fetype) = stack;
4142 /* name needs to be mangled */
4143 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4145 body = resolveSymbols (body); /* resolve the symbols */
4146 body = decorateType (body); /* propagateType & do semantic checks */
4148 ex = newAst_VALUE (symbolVal (name)); /* create name */
4149 ex = newNode (FUNCTION, ex, body);
4150 ex->values.args = FUNC_ARGS(name->type);
4152 if (options.dump_tree) PA(ex);
4155 werror (E_FUNC_NO_CODE, name->name);
4159 /* create the node & generate intermediate code */
4161 codeOutFile = code->oFile;
4162 piCode = iCodeFromAst (ex);
4166 werror (E_FUNC_NO_CODE, name->name);
4170 eBBlockFromiCode (piCode);
4172 /* if there are any statics then do them */
4175 GcurMemmap = statsg;
4176 codeOutFile = statsg->oFile;
4177 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4183 /* dealloc the block variables */
4184 processBlockVars (body, &stack, DEALLOCATE);
4185 /* deallocate paramaters */
4186 deallocParms (FUNC_ARGS(name->type));
4188 if (IFFUNC_ISREENT (name->type))
4191 /* we are done freeup memory & cleanup */
4195 FUNC_HASBODY(name->type) = 1;
4196 addSet (&operKeyReset, name);
4197 applyToSet (operKeyReset, resetParmKey);
4200 cdbStructBlock (1, cdbFile);
4202 cleanUpLevel (LabelTab, 0);
4203 cleanUpBlock (StructTab, 1);
4204 cleanUpBlock (TypedefTab, 1);
4206 xstack->syms = NULL;
4207 istack->syms = NULL;
4212 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4213 /*-----------------------------------------------------------------*/
4214 /* ast_print : prints the ast (for debugging purposes) */
4215 /*-----------------------------------------------------------------*/
4217 void ast_print (ast * tree, FILE *outfile, int indent)
4222 /* can print only decorated trees */
4223 if (!tree->decorated) return;
4225 /* if any child is an error | this one is an error do nothing */
4226 if (tree->isError ||
4227 (tree->left && tree->left->isError) ||
4228 (tree->right && tree->right->isError)) {
4229 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4233 /* print the line */
4234 /* if not block & function */
4235 if (tree->type == EX_OP &&
4236 (tree->opval.op != FUNCTION &&
4237 tree->opval.op != BLOCK &&
4238 tree->opval.op != NULLOP)) {
4241 if (tree->opval.op == FUNCTION) {
4243 value *args=FUNC_ARGS(tree->left->opval.val->type);
4244 fprintf(outfile,"FUNCTION (%s=%p) type (",
4245 tree->left->opval.val->name, tree);
4246 printTypeChain (tree->ftype,outfile);
4247 fprintf(outfile,") args (");
4250 fprintf (outfile, ", ");
4252 printTypeChain (args ? args->type : NULL, outfile);
4254 args= args ? args->next : NULL;
4256 fprintf(outfile,")\n");
4257 ast_print(tree->left,outfile,indent);
4258 ast_print(tree->right,outfile,indent);
4261 if (tree->opval.op == BLOCK) {
4262 symbol *decls = tree->values.sym;
4263 INDENT(indent,outfile);
4264 fprintf(outfile,"{\n");
4266 INDENT(indent+4,outfile);
4267 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4268 decls->name, decls);
4269 printTypeChain(decls->type,outfile);
4270 fprintf(outfile,")\n");
4272 decls = decls->next;
4274 ast_print(tree->right,outfile,indent+4);
4275 INDENT(indent,outfile);
4276 fprintf(outfile,"}\n");
4279 if (tree->opval.op == NULLOP) {
4280 fprintf(outfile,"\n");
4281 ast_print(tree->left,outfile,indent);
4282 fprintf(outfile,"\n");
4283 ast_print(tree->right,outfile,indent);
4286 INDENT(indent,outfile);
4288 /*------------------------------------------------------------------*/
4289 /*----------------------------*/
4290 /* leaf has been reached */
4291 /*----------------------------*/
4292 /* if this is of type value */
4293 /* just get the type */
4294 if (tree->type == EX_VALUE) {
4296 if (IS_LITERAL (tree->opval.val->etype)) {
4297 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4298 (int) floatFromVal(tree->opval.val),
4299 (int) floatFromVal(tree->opval.val),
4300 floatFromVal(tree->opval.val));
4301 } else if (tree->opval.val->sym) {
4302 /* if the undefined flag is set then give error message */
4303 if (tree->opval.val->sym->undefined) {
4304 fprintf(outfile,"UNDEFINED SYMBOL ");
4306 fprintf(outfile,"SYMBOL ");
4308 fprintf(outfile,"(%s=%p)",
4309 tree->opval.val->sym->name,tree);
4312 fprintf(outfile," type (");
4313 printTypeChain(tree->ftype,outfile);
4314 fprintf(outfile,")\n");
4316 fprintf(outfile,"\n");
4321 /* if type link for the case of cast */
4322 if (tree->type == EX_LINK) {
4323 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4324 printTypeChain(tree->opval.lnk,outfile);
4325 fprintf(outfile,")\n");
4330 /* depending on type of operator do */
4332 switch (tree->opval.op) {
4333 /*------------------------------------------------------------------*/
4334 /*----------------------------*/
4336 /*----------------------------*/
4338 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4339 printTypeChain(tree->ftype,outfile);
4340 fprintf(outfile,")\n");
4341 ast_print(tree->left,outfile,indent+4);
4342 ast_print(tree->right,outfile,indent+4);
4345 /*------------------------------------------------------------------*/
4346 /*----------------------------*/
4348 /*----------------------------*/
4350 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4351 printTypeChain(tree->ftype,outfile);
4352 fprintf(outfile,")\n");
4353 ast_print(tree->left,outfile,indent+4);
4354 ast_print(tree->right,outfile,indent+4);
4357 /*------------------------------------------------------------------*/
4358 /*----------------------------*/
4359 /* struct/union pointer */
4360 /*----------------------------*/
4362 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4363 printTypeChain(tree->ftype,outfile);
4364 fprintf(outfile,")\n");
4365 ast_print(tree->left,outfile,indent+4);
4366 ast_print(tree->right,outfile,indent+4);
4369 /*------------------------------------------------------------------*/
4370 /*----------------------------*/
4371 /* ++/-- operation */
4372 /*----------------------------*/
4373 case INC_OP: /* incerement operator unary so left only */
4374 fprintf(outfile,"INC_OP (%p) type (",tree);
4375 printTypeChain(tree->ftype,outfile);
4376 fprintf(outfile,")\n");
4377 ast_print(tree->left,outfile,indent+4);
4381 fprintf(outfile,"DEC_OP (%p) type (",tree);
4382 printTypeChain(tree->ftype,outfile);
4383 fprintf(outfile,")\n");
4384 ast_print(tree->left,outfile,indent+4);
4387 /*------------------------------------------------------------------*/
4388 /*----------------------------*/
4390 /*----------------------------*/
4393 fprintf(outfile,"& (%p) type (",tree);
4394 printTypeChain(tree->ftype,outfile);
4395 fprintf(outfile,")\n");
4396 ast_print(tree->left,outfile,indent+4);
4397 ast_print(tree->right,outfile,indent+4);
4399 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4400 printTypeChain(tree->ftype,outfile);
4401 fprintf(outfile,")\n");
4402 ast_print(tree->left,outfile,indent+4);
4403 ast_print(tree->right,outfile,indent+4);
4406 /*----------------------------*/
4408 /*----------------------------*/
4410 fprintf(outfile,"OR (%p) type (",tree);
4411 printTypeChain(tree->ftype,outfile);
4412 fprintf(outfile,")\n");
4413 ast_print(tree->left,outfile,indent+4);
4414 ast_print(tree->right,outfile,indent+4);
4416 /*------------------------------------------------------------------*/
4417 /*----------------------------*/
4419 /*----------------------------*/
4421 fprintf(outfile,"XOR (%p) type (",tree);
4422 printTypeChain(tree->ftype,outfile);
4423 fprintf(outfile,")\n");
4424 ast_print(tree->left,outfile,indent+4);
4425 ast_print(tree->right,outfile,indent+4);
4428 /*------------------------------------------------------------------*/
4429 /*----------------------------*/
4431 /*----------------------------*/
4433 fprintf(outfile,"DIV (%p) type (",tree);
4434 printTypeChain(tree->ftype,outfile);
4435 fprintf(outfile,")\n");
4436 ast_print(tree->left,outfile,indent+4);
4437 ast_print(tree->right,outfile,indent+4);
4439 /*------------------------------------------------------------------*/
4440 /*----------------------------*/
4442 /*----------------------------*/
4444 fprintf(outfile,"MOD (%p) type (",tree);
4445 printTypeChain(tree->ftype,outfile);
4446 fprintf(outfile,")\n");
4447 ast_print(tree->left,outfile,indent+4);
4448 ast_print(tree->right,outfile,indent+4);
4451 /*------------------------------------------------------------------*/
4452 /*----------------------------*/
4453 /* address dereference */
4454 /*----------------------------*/
4455 case '*': /* can be unary : if right is null then unary operation */
4457 fprintf(outfile,"DEREF (%p) type (",tree);
4458 printTypeChain(tree->ftype,outfile);
4459 fprintf(outfile,")\n");
4460 ast_print(tree->left,outfile,indent+4);
4463 /*------------------------------------------------------------------*/
4464 /*----------------------------*/
4465 /* multiplication */
4466 /*----------------------------*/
4467 fprintf(outfile,"MULT (%p) type (",tree);
4468 printTypeChain(tree->ftype,outfile);
4469 fprintf(outfile,")\n");
4470 ast_print(tree->left,outfile,indent+4);
4471 ast_print(tree->right,outfile,indent+4);
4475 /*------------------------------------------------------------------*/
4476 /*----------------------------*/
4477 /* unary '+' operator */
4478 /*----------------------------*/
4482 fprintf(outfile,"UPLUS (%p) type (",tree);
4483 printTypeChain(tree->ftype,outfile);
4484 fprintf(outfile,")\n");
4485 ast_print(tree->left,outfile,indent+4);
4487 /*------------------------------------------------------------------*/
4488 /*----------------------------*/
4490 /*----------------------------*/
4491 fprintf(outfile,"ADD (%p) type (",tree);
4492 printTypeChain(tree->ftype,outfile);
4493 fprintf(outfile,")\n");
4494 ast_print(tree->left,outfile,indent+4);
4495 ast_print(tree->right,outfile,indent+4);
4498 /*------------------------------------------------------------------*/
4499 /*----------------------------*/
4501 /*----------------------------*/
4502 case '-': /* can be unary */
4504 fprintf(outfile,"UMINUS (%p) type (",tree);
4505 printTypeChain(tree->ftype,outfile);
4506 fprintf(outfile,")\n");
4507 ast_print(tree->left,outfile,indent+4);
4509 /*------------------------------------------------------------------*/
4510 /*----------------------------*/
4512 /*----------------------------*/
4513 fprintf(outfile,"SUB (%p) type (",tree);
4514 printTypeChain(tree->ftype,outfile);
4515 fprintf(outfile,")\n");
4516 ast_print(tree->left,outfile,indent+4);
4517 ast_print(tree->right,outfile,indent+4);
4520 /*------------------------------------------------------------------*/
4521 /*----------------------------*/
4523 /*----------------------------*/
4525 fprintf(outfile,"COMPL (%p) type (",tree);
4526 printTypeChain(tree->ftype,outfile);
4527 fprintf(outfile,")\n");
4528 ast_print(tree->left,outfile,indent+4);
4530 /*------------------------------------------------------------------*/
4531 /*----------------------------*/
4533 /*----------------------------*/
4535 fprintf(outfile,"NOT (%p) type (",tree);
4536 printTypeChain(tree->ftype,outfile);
4537 fprintf(outfile,")\n");
4538 ast_print(tree->left,outfile,indent+4);
4540 /*------------------------------------------------------------------*/
4541 /*----------------------------*/
4543 /*----------------------------*/
4545 fprintf(outfile,"RRC (%p) type (",tree);
4546 printTypeChain(tree->ftype,outfile);
4547 fprintf(outfile,")\n");
4548 ast_print(tree->left,outfile,indent+4);
4552 fprintf(outfile,"RLC (%p) type (",tree);
4553 printTypeChain(tree->ftype,outfile);
4554 fprintf(outfile,")\n");
4555 ast_print(tree->left,outfile,indent+4);
4558 fprintf(outfile,"GETHBIT (%p) type (",tree);
4559 printTypeChain(tree->ftype,outfile);
4560 fprintf(outfile,")\n");
4561 ast_print(tree->left,outfile,indent+4);
4564 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4565 printTypeChain(tree->ftype,outfile);
4566 fprintf(outfile,")\n");
4567 ast_print(tree->left,outfile,indent+4);
4568 ast_print(tree->right,outfile,indent+4);
4571 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+4);
4575 ast_print(tree->right,outfile,indent+4);
4577 /*------------------------------------------------------------------*/
4578 /*----------------------------*/
4580 /*----------------------------*/
4581 case CAST: /* change the type */
4582 fprintf(outfile,"CAST (%p) from type (",tree);
4583 printTypeChain(tree->right->ftype,outfile);
4584 fprintf(outfile,") to type (");
4585 printTypeChain(tree->ftype,outfile);
4586 fprintf(outfile,")\n");
4587 ast_print(tree->right,outfile,indent+4);
4591 fprintf(outfile,"ANDAND (%p) type (",tree);
4592 printTypeChain(tree->ftype,outfile);
4593 fprintf(outfile,")\n");
4594 ast_print(tree->left,outfile,indent+4);
4595 ast_print(tree->right,outfile,indent+4);
4598 fprintf(outfile,"OROR (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+4);
4602 ast_print(tree->right,outfile,indent+4);
4605 /*------------------------------------------------------------------*/
4606 /*----------------------------*/
4607 /* comparison operators */
4608 /*----------------------------*/
4610 fprintf(outfile,"GT(>) (%p) type (",tree);
4611 printTypeChain(tree->ftype,outfile);
4612 fprintf(outfile,")\n");
4613 ast_print(tree->left,outfile,indent+4);
4614 ast_print(tree->right,outfile,indent+4);
4617 fprintf(outfile,"LT(<) (%p) type (",tree);
4618 printTypeChain(tree->ftype,outfile);
4619 fprintf(outfile,")\n");
4620 ast_print(tree->left,outfile,indent+4);
4621 ast_print(tree->right,outfile,indent+4);
4624 fprintf(outfile,"LE(<=) (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+4);
4628 ast_print(tree->right,outfile,indent+4);
4631 fprintf(outfile,"GE(>=) (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+4);
4635 ast_print(tree->right,outfile,indent+4);
4638 fprintf(outfile,"EQ(==) (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+4);
4642 ast_print(tree->right,outfile,indent+4);
4645 fprintf(outfile,"NE(!=) (%p) type (",tree);
4646 printTypeChain(tree->ftype,outfile);
4647 fprintf(outfile,")\n");
4648 ast_print(tree->left,outfile,indent+4);
4649 ast_print(tree->right,outfile,indent+4);
4650 /*------------------------------------------------------------------*/
4651 /*----------------------------*/
4653 /*----------------------------*/
4654 case SIZEOF: /* evaluate wihout code generation */
4655 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4658 /*------------------------------------------------------------------*/
4659 /*----------------------------*/
4660 /* conditional operator '?' */
4661 /*----------------------------*/
4663 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+4);
4667 ast_print(tree->right,outfile,indent+4);
4671 fprintf(outfile,"COLON(:) (%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 /* assignment operators */
4681 /*----------------------------*/
4683 fprintf(outfile,"MULASS(*=) (%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,"DIVASS(/=) (%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,"ANDASS(&=) (%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,"ORASS(*=) (%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,"XORASS(*=) (%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,"RSHFTASS(>>=) (%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);
4725 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4726 printTypeChain(tree->ftype,outfile);
4727 fprintf(outfile,")\n");
4728 ast_print(tree->left,outfile,indent+4);
4729 ast_print(tree->right,outfile,indent+4);
4731 /*------------------------------------------------------------------*/
4732 /*----------------------------*/
4734 /*----------------------------*/
4736 fprintf(outfile,"SUBASS(-=) (%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);
4742 /*------------------------------------------------------------------*/
4743 /*----------------------------*/
4745 /*----------------------------*/
4747 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4748 printTypeChain(tree->ftype,outfile);
4749 fprintf(outfile,")\n");
4750 ast_print(tree->left,outfile,indent+4);
4751 ast_print(tree->right,outfile,indent+4);
4753 /*------------------------------------------------------------------*/
4754 /*----------------------------*/
4755 /* straight assignemnt */
4756 /*----------------------------*/
4758 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4759 printTypeChain(tree->ftype,outfile);
4760 fprintf(outfile,")\n");
4761 ast_print(tree->left,outfile,indent+4);
4762 ast_print(tree->right,outfile,indent+4);
4764 /*------------------------------------------------------------------*/
4765 /*----------------------------*/
4766 /* comma operator */
4767 /*----------------------------*/
4769 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+4);
4773 ast_print(tree->right,outfile,indent+4);
4775 /*------------------------------------------------------------------*/
4776 /*----------------------------*/
4778 /*----------------------------*/
4781 fprintf(outfile,"CALL (%p) type (",tree);
4782 printTypeChain(tree->ftype,outfile);
4783 fprintf(outfile,")\n");
4784 ast_print(tree->left,outfile,indent+4);
4785 ast_print(tree->right,outfile,indent+4);
4788 fprintf(outfile,"PARMS\n");
4789 ast_print(tree->left,outfile,indent+4);
4790 if (tree->right && !IS_AST_PARAM(tree->right)) {
4791 ast_print(tree->right,outfile,indent+4);
4794 /*------------------------------------------------------------------*/
4795 /*----------------------------*/
4796 /* return statement */
4797 /*----------------------------*/
4799 fprintf(outfile,"RETURN (%p) type (",tree);
4800 printTypeChain(tree->right->ftype,outfile);
4801 fprintf(outfile,")\n");
4802 ast_print(tree->right,outfile,indent+4);
4804 /*------------------------------------------------------------------*/
4805 /*----------------------------*/
4806 /* label statement */
4807 /*----------------------------*/
4809 fprintf(outfile,"LABEL (%p)",tree);
4810 ast_print(tree->left,outfile,indent+4);
4811 ast_print(tree->right,outfile,indent);
4813 /*------------------------------------------------------------------*/
4814 /*----------------------------*/
4815 /* switch statement */
4816 /*----------------------------*/
4820 fprintf(outfile,"SWITCH (%p) ",tree);
4821 ast_print(tree->left,outfile,0);
4822 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4823 INDENT(indent+4,outfile);
4824 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4825 (int) floatFromVal(val),
4826 tree->values.switchVals.swNum,
4827 (int) floatFromVal(val));
4829 ast_print(tree->right,outfile,indent);
4832 /*------------------------------------------------------------------*/
4833 /*----------------------------*/
4835 /*----------------------------*/
4837 fprintf(outfile,"IF (%p) \n",tree);
4838 ast_print(tree->left,outfile,indent+4);
4839 if (tree->trueLabel) {
4840 INDENT(indent,outfile);
4841 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4843 if (tree->falseLabel) {
4844 INDENT(indent,outfile);
4845 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4847 ast_print(tree->right,outfile,indent+4);
4849 /*------------------------------------------------------------------*/
4850 /*----------------------------*/
4852 /*----------------------------*/
4854 fprintf(outfile,"FOR (%p) \n",tree);
4855 if (AST_FOR( tree, initExpr)) {
4856 INDENT(indent+4,outfile);
4857 fprintf(outfile,"INIT EXPR ");
4858 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4860 if (AST_FOR( tree, condExpr)) {
4861 INDENT(indent+4,outfile);
4862 fprintf(outfile,"COND EXPR ");
4863 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4865 if (AST_FOR( tree, loopExpr)) {
4866 INDENT(indent+4,outfile);
4867 fprintf(outfile,"LOOP EXPR ");
4868 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4870 fprintf(outfile,"FOR LOOP BODY \n");
4871 ast_print(tree->left,outfile,indent+4);
4880 ast_print(t,stdout,0);