1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
30 set *operKeyReset = NULL;
31 ast *staticAutos = NULL;
34 #define LRVAL(x) x->left->rvalue
35 #define RRVAL(x) x->right->rvalue
36 #define TRVAL(x) x->rvalue
37 #define LLVAL(x) x->left->lvalue
38 #define RLVAL(x) x->right->lvalue
39 #define TLVAL(x) x->lvalue
40 #define RTYPE(x) x->right->ftype
41 #define RETYPE(x) x->right->etype
42 #define LTYPE(x) x->left->ftype
43 #define LETYPE(x) x->left->etype
44 #define TTYPE(x) x->ftype
45 #define TETYPE(x) x->etype
53 ast *createIval (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
74 newAst (int type, void *op)
77 static int oldLineno = 0;
79 Safe_calloc (1, ex, sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : yylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
88 /* depending on the type */
92 ex->opval.val = (value *) op;
95 ex->opval.op = (long) op;
98 ex->opval.lnk = (sym_link *) op;
101 ex->opval.stmnt = (unsigned) op;
109 newAst_ (unsigned type)
112 static int oldLineno = 0;
114 ex = Safe_calloc (1, sizeof (ast));
117 ex->lineno = (noLineno ? oldLineno : yylineno);
118 ex->filename = currFname;
119 ex->level = NestLevel;
120 ex->block = currBlockno;
121 ex->initMode = inInitMode;
126 newAst_VALUE (value * val)
128 ast *ex = newAst_ (EX_VALUE);
134 newAst_OP (unsigned op)
136 ast *ex = newAst_ (EX_OP);
142 newAst_LINK (sym_link * val)
144 ast *ex = newAst_ (EX_LINK);
150 newAst_STMNT (unsigned val)
152 ast *ex = newAst_ (EX_STMNT);
153 ex->opval.stmnt = val;
157 /*-----------------------------------------------------------------*/
158 /* newNode - creates a new node */
159 /*-----------------------------------------------------------------*/
161 newNode (long op, ast * left, ast * right)
172 /*-----------------------------------------------------------------*/
173 /* newIfxNode - creates a new Ifx Node */
174 /*-----------------------------------------------------------------*/
176 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
180 /* if this is a literal then we already know the result */
181 if (condAst->etype && IS_LITERAL (condAst->etype))
183 /* then depending on the expression value */
184 if (floatFromVal (condAst->opval.val))
185 ifxNode = newNode (GOTO,
186 newAst_VALUE (symbolVal (trueLabel)),
189 ifxNode = newNode (GOTO,
190 newAst_VALUE (symbolVal (falseLabel)),
195 ifxNode = newNode (IFX, condAst, NULL);
196 ifxNode->trueLabel = trueLabel;
197 ifxNode->falseLabel = falseLabel;
203 /*-----------------------------------------------------------------*/
204 /* copyAstValues - copies value portion of ast if needed */
205 /*-----------------------------------------------------------------*/
207 copyAstValues (ast * dest, ast * src)
209 switch (src->opval.op)
212 dest->values.sym = copySymbolChain (src->values.sym);
216 dest->values.switchVals.swVals =
217 copyValue (src->values.switchVals.swVals);
218 dest->values.switchVals.swDefault =
219 src->values.switchVals.swDefault;
220 dest->values.switchVals.swNum =
221 src->values.switchVals.swNum;
225 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
226 strcpy (dest->values.inlineasm, src->values.inlineasm);
230 dest->values.constlist = copyLiteralList(src->values.constlist);
234 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
235 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
236 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
237 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
238 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
239 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
240 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
245 /*-----------------------------------------------------------------*/
246 /* copyAst - makes a copy of a given astession */
247 /*-----------------------------------------------------------------*/
256 dest = Safe_calloc (1, sizeof (ast));
258 dest->type = src->type;
259 dest->lineno = src->lineno;
260 dest->level = src->level;
261 dest->funcName = src->funcName;
262 dest->argSym = src->argSym;
264 /* if this is a leaf */
266 if (src->type == EX_VALUE)
268 dest->opval.val = copyValue (src->opval.val);
273 if (src->type == EX_LINK)
275 dest->opval.lnk = copyLinkChain (src->opval.lnk);
279 dest->opval.op = src->opval.op;
281 /* if this is a node that has special values */
282 copyAstValues (dest, src);
285 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
287 dest->trueLabel = copySymbol (src->trueLabel);
288 dest->falseLabel = copySymbol (src->falseLabel);
289 dest->left = copyAst (src->left);
290 dest->right = copyAst (src->right);
296 /*-----------------------------------------------------------------*/
297 /* hasSEFcalls - returns TRUE if tree has a function call */
298 /*-----------------------------------------------------------------*/
300 hasSEFcalls (ast * tree)
305 if (tree->type == EX_OP &&
306 (tree->opval.op == CALL ||
307 tree->opval.op == PCALL ||
308 tree->opval.op == '=' ||
309 tree->opval.op == INC_OP ||
310 tree->opval.op == DEC_OP))
313 return (hasSEFcalls (tree->left) |
314 hasSEFcalls (tree->right));
317 /*-----------------------------------------------------------------*/
318 /* isAstEqual - compares two asts & returns 1 if they are equal */
319 /*-----------------------------------------------------------------*/
321 isAstEqual (ast * t1, ast * t2)
330 if (t1->type != t2->type)
336 if (t1->opval.op != t2->opval.op)
338 return (isAstEqual (t1->left, t2->left) &&
339 isAstEqual (t1->right, t2->right));
343 if (t1->opval.val->sym)
345 if (!t2->opval.val->sym)
348 return isSymbolEqual (t1->opval.val->sym,
353 if (t2->opval.val->sym)
356 return (floatFromVal (t1->opval.val) ==
357 floatFromVal (t2->opval.val));
361 /* only compare these two types */
369 /*-----------------------------------------------------------------*/
370 /* resolveSymbols - resolve symbols from the symbol table */
371 /*-----------------------------------------------------------------*/
373 resolveSymbols (ast * tree)
375 /* walk the entire tree and check for values */
376 /* with symbols if we find one then replace */
377 /* symbol with that from the symbol table */
383 /* if not block & function */
384 if (tree->type == EX_OP &&
385 (tree->opval.op != FUNCTION &&
386 tree->opval.op != BLOCK &&
387 tree->opval.op != NULLOP))
389 filename = tree->filename;
390 lineno = tree->lineno;
393 /* make sure we resolve the true & false labels for ifx */
394 if (tree->type == EX_OP && tree->opval.op == IFX)
400 if ((csym = findSym (LabelTab, tree->trueLabel,
401 tree->trueLabel->name)))
402 tree->trueLabel = csym;
404 werror (E_LABEL_UNDEF, tree->trueLabel->name);
407 if (tree->falseLabel)
409 if ((csym = findSym (LabelTab,
411 tree->falseLabel->name)))
412 tree->falseLabel = csym;
414 werror (E_LABEL_UNDEF, tree->falseLabel->name);
419 /* if this is a label resolve it from the labelTab */
420 if (IS_AST_VALUE (tree) &&
421 tree->opval.val->sym &&
422 tree->opval.val->sym->islbl)
425 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
426 tree->opval.val->sym->name);
429 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
431 tree->opval.val->sym = csym;
433 goto resolveChildren;
436 /* do only for leafs */
437 if (IS_AST_VALUE (tree) &&
438 tree->opval.val->sym &&
439 !tree->opval.val->sym->implicit)
442 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
444 /* if found in the symbol table & they r not the same */
445 if (csym && tree->opval.val->sym != csym)
447 tree->opval.val->sym = csym;
448 tree->opval.val->type = csym->type;
449 tree->opval.val->etype = csym->etype;
452 /* if not found in the symbol table */
453 /* mark it as undefined assume it is */
454 /* an integer in data space */
455 if (!csym && !tree->opval.val->sym->implicit)
458 /* if this is a function name then */
459 /* mark it as returning an int */
462 tree->opval.val->sym->type = newLink ();
463 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
464 tree->opval.val->sym->type->next =
465 tree->opval.val->sym->etype = newIntLink ();
466 tree->opval.val->etype = tree->opval.val->etype;
467 tree->opval.val->type = tree->opval.val->sym->type;
468 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
469 allocVariables (tree->opval.val->sym);
473 tree->opval.val->sym->undefined = 1;
474 tree->opval.val->type =
475 tree->opval.val->etype = newIntLink ();
476 tree->opval.val->sym->type =
477 tree->opval.val->sym->etype = newIntLink ();
483 resolveSymbols (tree->left);
484 resolveSymbols (tree->right);
489 /*-----------------------------------------------------------------*/
490 /* setAstLineno - walks a ast tree & sets the line number */
491 /*-----------------------------------------------------------------*/
493 setAstLineno (ast * tree, int lineno)
498 tree->lineno = lineno;
499 setAstLineno (tree->left, lineno);
500 setAstLineno (tree->right, lineno);
505 /* this functions seems to be superfluous?! kmh */
507 /*-----------------------------------------------------------------*/
508 /* resolveFromTable - will return the symbal table value */
509 /*-----------------------------------------------------------------*/
511 resolveFromTable (value * val)
518 csym = findSymWithLevel (SymbolTab, val->sym);
520 /* if found in the symbol table & they r not the same */
521 if (csym && val->sym != csym &&
522 csym->level == val->sym->level &&
528 val->type = csym->type;
529 val->etype = csym->etype;
536 /*-----------------------------------------------------------------*/
537 /* funcOfType :- function of type with name */
538 /*-----------------------------------------------------------------*/
540 funcOfType (char *name, sym_link * type, sym_link * argType,
544 /* create the symbol */
545 sym = newSymbol (name, 0);
547 /* if arguments required */
552 args = sym->args = newValue ();
556 args->type = copyLinkChain (argType);
557 args->etype = getSpec (args->type);
560 args = args->next = newValue ();
564 /* setup return value */
565 sym->type = newLink ();
566 DCL_TYPE (sym->type) = FUNCTION;
567 sym->type->next = copyLinkChain (type);
568 sym->etype = getSpec (sym->type);
569 SPEC_RENT (sym->etype) = rent;
574 allocVariables (sym);
579 /*-----------------------------------------------------------------*/
580 /* reverseParms - will reverse a parameter tree */
581 /*-----------------------------------------------------------------*/
583 reverseParms (ast * ptree)
589 /* top down if we find a nonParm tree then quit */
590 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
593 ptree->left = ptree->right;
594 ptree->right = ttree;
595 reverseParms (ptree->left);
596 reverseParms (ptree->right);
602 /*-----------------------------------------------------------------*/
603 /* processParms - makes sure the parameters are okay and do some */
604 /* processing with them */
605 /*-----------------------------------------------------------------*/
607 processParms (ast * func,
614 sym_link *fetype = func->etype;
616 /* if none of them exist */
617 if (!defParm && !actParm)
621 if (getenv("DEBUG_SANITY")) {
622 fprintf (stderr, "addSym: %s ", defParm->name);
624 /* make sure the type is complete and sane */
625 checkTypeSanity(defParm->etype, defParm->name);
628 /* if the function is being called via a pointer & */
629 /* it has not been defined a reentrant then we cannot */
630 /* have parameters */
631 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
633 werror (W_NONRENT_ARGS);
637 /* if defined parameters ended but actual parameters */
638 /* exist and this is not defined as a variable arg */
639 /* also check if statckAuto option is specified */
640 if ((!defParm) && actParm && (!func->hasVargs) &&
641 !options.stackAuto && !IS_RENT (fetype))
643 werror (E_TOO_MANY_PARMS);
647 /* if defined parameters present but no actual parameters */
648 if (defParm && !actParm)
650 werror (E_TOO_FEW_PARMS);
654 /* If this is a varargs function... */
655 if (!defParm && actParm && func->hasVargs)
660 if (IS_CAST_OP (actParm)
661 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
663 /* Parameter was explicitly typecast; don't touch it. */
667 /* The ternary ('?') operator is weird: the ftype of the
668 * operator is the type of the condition, but it will return a
669 * (possibly) different type.
671 if (IS_TERNARY_OP(actParm))
673 assert(IS_COLON_OP(actParm->right));
674 assert(actParm->right->left);
675 ftype = actParm->right->left->ftype;
679 ftype = actParm->ftype;
682 /* If it's a small integer, upcast to int. */
683 if (IS_INTEGRAL (ftype)
684 && (getSize (ftype) < (unsigned) INTSIZE))
686 newType = newAst_LINK(INTTYPE);
689 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
691 newType = newAst_LINK (copyLinkChain(ftype));
692 DCL_TYPE (newType->opval.lnk) = GPOINTER;
695 if (IS_AGGREGATE (ftype))
697 newType = newAst_LINK (copyLinkChain (ftype));
698 DCL_TYPE (newType->opval.lnk) = GPOINTER;
702 /* cast required; change this op to a cast. */
703 ast *parmCopy = resolveSymbols (copyAst (actParm));
705 actParm->type = EX_OP;
706 actParm->opval.op = CAST;
707 actParm->left = newType;
708 actParm->right = parmCopy;
709 decorateType (actParm);
711 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
713 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
714 processParms (func, NULL, actParm->right, parmNumber, rightmost));
719 /* if defined parameters ended but actual has not & */
721 if (!defParm && actParm &&
722 (options.stackAuto || IS_RENT (fetype)))
725 resolveSymbols (actParm);
726 /* if this is a PARAM node then match left & right */
727 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
729 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
730 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
734 /* If we have found a value node by following only right-hand links,
735 * then we know that there are no more values after us.
737 * Therefore, if there are more defined parameters, the caller didn't
740 if (rightmost && defParm->next)
742 werror (E_TOO_FEW_PARMS);
748 /* the parameter type must be at least castable */
749 if (compareType (defParm->type, actParm->ftype) == 0)
755 if (!IS_SPEC(defParm->type) && !IS_SPEC(actParm->ftype)) {
756 // now we have two pointers, check if they point to the same
757 sym_link *dtype=defParm->type, *atype=actParm->ftype;
762 (dtype->next && !atype->next) ||
763 (!dtype->next && atype->next) ||
764 compareType (dtype, atype)!=1) {
767 } while (dtype->next && atype->next);
768 if (IS_SPEC(dtype) && IS_SPEC(atype)) {
769 // ok so far, we have two etypes, they must have the same SCLASS
770 if (SPEC_SCLS(dtype)!=SPEC_SCLS(atype)) {
778 werror (W_INCOMPAT_CAST);
779 fprintf (stderr, "type --> '");
780 printTypeChain (actParm->ftype, stderr);
781 fprintf (stderr, "' ");
782 fprintf (stderr, "assigned to type --> '");
783 printTypeChain (defParm->type, stderr);
784 fprintf (stderr, "'\n");
787 /* if the parameter is castable then add the cast */
788 if (compareType (defParm->type, actParm->ftype) < 0)
790 ast *pTree = resolveSymbols (copyAst (actParm));
792 /* now change the current one to a cast */
793 actParm->type = EX_OP;
794 actParm->opval.op = CAST;
795 actParm->left = newAst_LINK (defParm->type);
796 actParm->right = pTree;
797 actParm->etype = defParm->etype;
798 actParm->ftype = defParm->type;
801 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
803 actParm->argSym = defParm->sym;
804 /* make a copy and change the regparm type to the defined parm */
805 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
806 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
810 /*-----------------------------------------------------------------*/
811 /* createIvalType - generates ival for basic types */
812 /*-----------------------------------------------------------------*/
814 createIvalType (ast * sym, sym_link * type, initList * ilist)
818 /* if initList is deep */
819 if (ilist->type == INIT_DEEP)
820 ilist = ilist->init.deep;
822 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
823 return decorateType (newNode ('=', sym, iExpr));
826 /*-----------------------------------------------------------------*/
827 /* createIvalStruct - generates initial value for structures */
828 /*-----------------------------------------------------------------*/
830 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
836 sflds = SPEC_STRUCT (type)->fields;
837 if (ilist->type != INIT_DEEP)
839 werror (E_INIT_STRUCT, "");
843 iloop = ilist->init.deep;
845 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
849 /* if we have come to end */
853 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
854 lAst = decorateType (resolveSymbols (lAst));
855 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
861 /*-----------------------------------------------------------------*/
862 /* createIvalArray - generates code for array initialization */
863 /*-----------------------------------------------------------------*/
865 createIvalArray (ast * sym, sym_link * type, initList * ilist)
869 int lcnt = 0, size = 0;
870 literalList *literalL;
872 /* take care of the special case */
873 /* array of characters can be init */
875 if (IS_CHAR (type->next))
876 if ((rast = createIvalCharPtr (sym,
878 decorateType (resolveSymbols (list2expr (ilist))))))
880 return decorateType (resolveSymbols (rast));
882 /* not the special case */
883 if (ilist->type != INIT_DEEP)
885 werror (E_INIT_STRUCT, "");
889 iloop = ilist->init.deep;
890 lcnt = DCL_ELEM (type);
892 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
896 aSym = decorateType (resolveSymbols(sym));
898 rast = newNode(ARRAYINIT, aSym, NULL);
899 rast->values.constlist = literalL;
901 // Make sure size is set to length of initializer list.
908 if (lcnt && size > lcnt)
910 // Array size was specified, and we have more initializers than needed.
911 char *name=sym->opval.val->sym->name;
912 int lineno=sym->opval.val->sym->lineDef;
914 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
923 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
924 aSym = decorateType (resolveSymbols (aSym));
925 rast = createIval (aSym, type->next, iloop, rast);
926 iloop = (iloop ? iloop->next : NULL);
932 /* no of elements given and we */
933 /* have generated for all of them */
936 // there has to be a better way
937 char *name=sym->opval.val->sym->name;
938 int lineno=sym->opval.val->sym->lineDef;
939 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
946 /* if we have not been given a size */
947 if (!DCL_ELEM (type))
949 DCL_ELEM (type) = size;
952 return decorateType (resolveSymbols (rast));
956 /*-----------------------------------------------------------------*/
957 /* createIvalCharPtr - generates initial values for char pointers */
958 /*-----------------------------------------------------------------*/
960 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
964 /* if this is a pointer & right is a literal array then */
965 /* just assignment will do */
966 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
967 SPEC_SCLS (iexpr->etype) == S_CODE)
968 && IS_ARRAY (iexpr->ftype)))
969 return newNode ('=', sym, iexpr);
971 /* left side is an array so we have to assign each */
973 if ((IS_LITERAL (iexpr->etype) ||
974 SPEC_SCLS (iexpr->etype) == S_CODE)
975 && IS_ARRAY (iexpr->ftype))
977 /* for each character generate an assignment */
978 /* to the array element */
979 char *s = SPEC_CVAL (iexpr->etype).v_char;
984 rast = newNode (NULLOP,
988 newAst_VALUE (valueFromLit ((float) i))),
989 newAst_VALUE (valueFromLit (*s))));
993 rast = newNode (NULLOP,
997 newAst_VALUE (valueFromLit ((float) i))),
998 newAst_VALUE (valueFromLit (*s))));
999 return decorateType (resolveSymbols (rast));
1005 /*-----------------------------------------------------------------*/
1006 /* createIvalPtr - generates initial value for pointers */
1007 /*-----------------------------------------------------------------*/
1009 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1015 if (ilist->type == INIT_DEEP)
1016 ilist = ilist->init.deep;
1018 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1020 /* if character pointer */
1021 if (IS_CHAR (type->next))
1022 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1025 return newNode ('=', sym, iexpr);
1028 /*-----------------------------------------------------------------*/
1029 /* createIval - generates code for initial value */
1030 /*-----------------------------------------------------------------*/
1032 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1039 /* if structure then */
1040 if (IS_STRUCT (type))
1041 rast = createIvalStruct (sym, type, ilist);
1043 /* if this is a pointer */
1045 rast = createIvalPtr (sym, type, ilist);
1047 /* if this is an array */
1048 if (IS_ARRAY (type))
1049 rast = createIvalArray (sym, type, ilist);
1051 /* if type is SPECIFIER */
1053 rast = createIvalType (sym, type, ilist);
1056 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1058 return decorateType (resolveSymbols (rast));
1061 /*-----------------------------------------------------------------*/
1062 /* initAggregates - initialises aggregate variables with initv */
1063 /*-----------------------------------------------------------------*/
1065 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1067 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1071 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1073 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1074 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1075 "with -mmcs51 and --model-large");
1079 if (SPEC_OCLS(sym->etype)==xdata &&
1080 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1083 newSym=copySymbol (sym);
1084 SPEC_OCLS(newSym->etype)=code;
1085 sprintf (newSym->name, "%s_init__", sym->name);
1086 sprintf (newSym->rname,"%s_init__", sym->rname);
1087 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1089 // emit it in the static segment
1090 addSet(&statsg->syms, newSym);
1092 // now memcpy() the entire array from cseg
1093 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1094 newAst_VALUE (symbolVal (sym)),
1095 newAst_VALUE (symbolVal (newSym)));
1096 return decorateType(resolveSymbols(ast));
1100 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1103 /*-----------------------------------------------------------------*/
1104 /* gatherAutoInit - creates assignment expressions for initial */
1106 /*-----------------------------------------------------------------*/
1108 gatherAutoInit (symbol * autoChain)
1115 for (sym = autoChain; sym; sym = sym->next)
1118 /* resolve the symbols in the ival */
1120 resolveIvalSym (sym->ival);
1122 /* if this is a static variable & has an */
1123 /* initial value the code needs to be lifted */
1124 /* here to the main portion since they can be */
1125 /* initialised only once at the start */
1126 if (IS_STATIC (sym->etype) && sym->ival &&
1127 SPEC_SCLS (sym->etype) != S_CODE)
1131 // this can only be a constant
1132 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1133 werror (E_CONST_EXPECTED);
1136 /* insert the symbol into the symbol table */
1137 /* with level = 0 & name = rname */
1138 newSym = copySymbol (sym);
1139 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1141 /* now lift the code to main */
1142 if (IS_AGGREGATE (sym->type))
1143 work = initAggregates (sym, sym->ival, NULL);
1145 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1146 list2expr (sym->ival));
1148 setAstLineno (work, sym->lineDef);
1152 staticAutos = newNode (NULLOP, staticAutos, work);
1159 /* if there is an initial value */
1160 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1162 if (IS_AGGREGATE (sym->type))
1163 work = initAggregates (sym, sym->ival, NULL);
1165 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1166 list2expr (sym->ival));
1168 setAstLineno (work, sym->lineDef);
1171 init = newNode (NULLOP, init, work);
1180 /*-----------------------------------------------------------------*/
1181 /* stringToSymbol - creates a symbol from a literal string */
1182 /*-----------------------------------------------------------------*/
1184 stringToSymbol (value * val)
1186 char name[SDCC_NAME_MAX + 1];
1187 static int charLbl = 0;
1190 sprintf (name, "_str_%d", charLbl++);
1191 sym = newSymbol (name, 0); /* make it @ level 0 */
1192 strcpy (sym->rname, name);
1194 /* copy the type from the value passed */
1195 sym->type = copyLinkChain (val->type);
1196 sym->etype = getSpec (sym->type);
1197 /* change to storage class & output class */
1198 SPEC_SCLS (sym->etype) = S_CODE;
1199 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1200 SPEC_STAT (sym->etype) = 1;
1201 /* make the level & block = 0 */
1202 sym->block = sym->level = 0;
1204 /* create an ival */
1205 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1210 allocVariables (sym);
1213 return symbolVal (sym);
1217 /*-----------------------------------------------------------------*/
1218 /* processBlockVars - will go thru the ast looking for block if */
1219 /* a block is found then will allocate the syms */
1220 /* will also gather the auto inits present */
1221 /*-----------------------------------------------------------------*/
1223 processBlockVars (ast * tree, int *stack, int action)
1228 /* if this is a block */
1229 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1233 if (action == ALLOCATE)
1235 *stack += allocVariables (tree->values.sym);
1236 autoInit = gatherAutoInit (tree->values.sym);
1238 /* if there are auto inits then do them */
1240 tree->left = newNode (NULLOP, autoInit, tree->left);
1242 else /* action is deallocate */
1243 deallocLocal (tree->values.sym);
1246 processBlockVars (tree->left, stack, action);
1247 processBlockVars (tree->right, stack, action);
1251 /*-----------------------------------------------------------------*/
1252 /* constExprValue - returns the value of a constant expression */
1253 /*-----------------------------------------------------------------*/
1255 constExprValue (ast * cexpr, int check)
1257 cexpr = decorateType (resolveSymbols (cexpr));
1259 /* if this is not a constant then */
1260 if (!IS_LITERAL (cexpr->ftype))
1262 /* then check if this is a literal array
1264 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1265 SPEC_CVAL (cexpr->etype).v_char &&
1266 IS_ARRAY (cexpr->ftype))
1268 value *val = valFromType (cexpr->ftype);
1269 SPEC_SCLS (val->etype) = S_LITERAL;
1270 val->sym = cexpr->opval.val->sym;
1271 val->sym->type = copyLinkChain (cexpr->ftype);
1272 val->sym->etype = getSpec (val->sym->type);
1273 strcpy (val->name, cexpr->opval.val->sym->rname);
1277 /* if we are casting a literal value then */
1278 if (IS_AST_OP (cexpr) &&
1279 cexpr->opval.op == CAST &&
1280 IS_LITERAL (cexpr->left->ftype))
1281 return valCastLiteral (cexpr->ftype,
1282 floatFromVal (cexpr->left->opval.val));
1284 if (IS_AST_VALUE (cexpr))
1285 return cexpr->opval.val;
1288 werror (E_CONST_EXPECTED, "found expression");
1293 /* return the value */
1294 return cexpr->opval.val;
1298 /*-----------------------------------------------------------------*/
1299 /* isLabelInAst - will return true if a given label is found */
1300 /*-----------------------------------------------------------------*/
1302 isLabelInAst (symbol * label, ast * tree)
1304 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1307 if (IS_AST_OP (tree) &&
1308 tree->opval.op == LABEL &&
1309 isSymbolEqual (AST_SYMBOL (tree->left), label))
1312 return isLabelInAst (label, tree->right) &&
1313 isLabelInAst (label, tree->left);
1317 /*-----------------------------------------------------------------*/
1318 /* isLoopCountable - return true if the loop count can be determi- */
1319 /* -ned at compile time . */
1320 /*-----------------------------------------------------------------*/
1322 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1323 symbol ** sym, ast ** init, ast ** end)
1326 /* the loop is considered countable if the following
1327 conditions are true :-
1329 a) initExpr :- <sym> = <const>
1330 b) condExpr :- <sym> < <const1>
1331 c) loopExpr :- <sym> ++
1334 /* first check the initExpr */
1335 if (IS_AST_OP (initExpr) &&
1336 initExpr->opval.op == '=' && /* is assignment */
1337 IS_AST_SYM_VALUE (initExpr->left))
1338 { /* left is a symbol */
1340 *sym = AST_SYMBOL (initExpr->left);
1341 *init = initExpr->right;
1346 /* for now the symbol has to be of
1348 if (!IS_INTEGRAL ((*sym)->type))
1351 /* now check condExpr */
1352 if (IS_AST_OP (condExpr))
1355 switch (condExpr->opval.op)
1358 if (IS_AST_SYM_VALUE (condExpr->left) &&
1359 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1360 IS_AST_LIT_VALUE (condExpr->right))
1362 *end = condExpr->right;
1368 if (IS_AST_OP (condExpr->left) &&
1369 condExpr->left->opval.op == '>' &&
1370 IS_AST_LIT_VALUE (condExpr->left->right) &&
1371 IS_AST_SYM_VALUE (condExpr->left->left) &&
1372 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1375 *end = newNode ('+', condExpr->left->right,
1376 newAst_VALUE (constVal ("1")));
1387 /* check loop expression is of the form <sym>++ */
1388 if (!IS_AST_OP (loopExpr))
1391 /* check if <sym> ++ */
1392 if (loopExpr->opval.op == INC_OP)
1398 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1399 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1406 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1407 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1415 if (loopExpr->opval.op == ADD_ASSIGN)
1418 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1419 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1420 IS_AST_LIT_VALUE (loopExpr->right) &&
1421 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1429 /*-----------------------------------------------------------------*/
1430 /* astHasVolatile - returns true if ast contains any volatile */
1431 /*-----------------------------------------------------------------*/
1433 astHasVolatile (ast * tree)
1438 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1441 if (IS_AST_OP (tree))
1442 return astHasVolatile (tree->left) ||
1443 astHasVolatile (tree->right);
1448 /*-----------------------------------------------------------------*/
1449 /* astHasPointer - return true if the ast contains any ptr variable */
1450 /*-----------------------------------------------------------------*/
1452 astHasPointer (ast * tree)
1457 if (IS_AST_LINK (tree))
1460 /* if we hit an array expression then check
1461 only the left side */
1462 if (IS_AST_OP (tree) && tree->opval.op == '[')
1463 return astHasPointer (tree->left);
1465 if (IS_AST_VALUE (tree))
1466 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1468 return astHasPointer (tree->left) ||
1469 astHasPointer (tree->right);
1473 /*-----------------------------------------------------------------*/
1474 /* astHasSymbol - return true if the ast has the given symbol */
1475 /*-----------------------------------------------------------------*/
1477 astHasSymbol (ast * tree, symbol * sym)
1479 if (!tree || IS_AST_LINK (tree))
1482 if (IS_AST_VALUE (tree))
1484 if (IS_AST_SYM_VALUE (tree))
1485 return isSymbolEqual (AST_SYMBOL (tree), sym);
1490 return astHasSymbol (tree->left, sym) ||
1491 astHasSymbol (tree->right, sym);
1494 /*-----------------------------------------------------------------*/
1495 /* astHasDeref - return true if the ast has an indirect access */
1496 /*-----------------------------------------------------------------*/
1498 astHasDeref (ast * tree)
1500 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1503 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1505 return astHasDeref (tree->left) || astHasDeref (tree->right);
1508 /*-----------------------------------------------------------------*/
1509 /* isConformingBody - the loop body has to conform to a set of rules */
1510 /* for the loop to be considered reversible read on for rules */
1511 /*-----------------------------------------------------------------*/
1513 isConformingBody (ast * pbody, symbol * sym, ast * body)
1516 /* we are going to do a pre-order traversal of the
1517 tree && check for the following conditions. (essentially
1518 a set of very shallow tests )
1519 a) the sym passed does not participate in
1520 any arithmetic operation
1521 b) There are no function calls
1522 c) all jumps are within the body
1523 d) address of loop control variable not taken
1524 e) if an assignment has a pointer on the
1525 left hand side make sure right does not have
1526 loop control variable */
1528 /* if we reach the end or a leaf then true */
1529 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1533 /* if anything else is "volatile" */
1534 if (IS_VOLATILE (TETYPE (pbody)))
1537 /* we will walk the body in a pre-order traversal for
1539 switch (pbody->opval.op)
1541 /*------------------------------------------------------------------*/
1543 return isConformingBody (pbody->right, sym, body);
1545 /*------------------------------------------------------------------*/
1550 /*------------------------------------------------------------------*/
1551 case INC_OP: /* incerement operator unary so left only */
1554 /* sure we are not sym is not modified */
1556 IS_AST_SYM_VALUE (pbody->left) &&
1557 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1561 IS_AST_SYM_VALUE (pbody->right) &&
1562 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1567 /*------------------------------------------------------------------*/
1569 case '*': /* can be unary : if right is null then unary operation */
1574 /* if right is NULL then unary operation */
1575 /*------------------------------------------------------------------*/
1576 /*----------------------------*/
1578 /*----------------------------*/
1581 if (IS_AST_SYM_VALUE (pbody->left) &&
1582 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1585 return isConformingBody (pbody->left, sym, body);
1589 if (astHasSymbol (pbody->left, sym) ||
1590 astHasSymbol (pbody->right, sym))
1595 /*------------------------------------------------------------------*/
1603 if (IS_AST_SYM_VALUE (pbody->left) &&
1604 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1607 if (IS_AST_SYM_VALUE (pbody->right) &&
1608 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1611 return isConformingBody (pbody->left, sym, body) &&
1612 isConformingBody (pbody->right, sym, body);
1619 if (IS_AST_SYM_VALUE (pbody->left) &&
1620 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1622 return isConformingBody (pbody->left, sym, body);
1624 /*------------------------------------------------------------------*/
1636 case SIZEOF: /* evaluate wihout code generation */
1638 return isConformingBody (pbody->left, sym, body) &&
1639 isConformingBody (pbody->right, sym, body);
1641 /*------------------------------------------------------------------*/
1644 /* if left has a pointer & right has loop
1645 control variable then we cannot */
1646 if (astHasPointer (pbody->left) &&
1647 astHasSymbol (pbody->right, sym))
1649 if (astHasVolatile (pbody->left))
1652 if (IS_AST_SYM_VALUE (pbody->left) &&
1653 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1656 if (astHasVolatile (pbody->left))
1659 if (astHasDeref(pbody->right)) return FALSE;
1661 return isConformingBody (pbody->left, sym, body) &&
1662 isConformingBody (pbody->right, sym, body);
1673 assert ("Parser should not have generated this\n");
1675 /*------------------------------------------------------------------*/
1676 /*----------------------------*/
1677 /* comma operator */
1678 /*----------------------------*/
1680 return isConformingBody (pbody->left, sym, body) &&
1681 isConformingBody (pbody->right, sym, body);
1683 /*------------------------------------------------------------------*/
1684 /*----------------------------*/
1686 /*----------------------------*/
1690 /*------------------------------------------------------------------*/
1691 /*----------------------------*/
1692 /* return statement */
1693 /*----------------------------*/
1698 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1703 if (astHasSymbol (pbody->left, sym))
1710 return isConformingBody (pbody->left, sym, body) &&
1711 isConformingBody (pbody->right, sym, body);
1717 /*-----------------------------------------------------------------*/
1718 /* isLoopReversible - takes a for loop as input && returns true */
1719 /* if the for loop is reversible. If yes will set the value of */
1720 /* the loop control var & init value & termination value */
1721 /*-----------------------------------------------------------------*/
1723 isLoopReversible (ast * loop, symbol ** loopCntrl,
1724 ast ** init, ast ** end)
1726 /* if option says don't do it then don't */
1727 if (optimize.noLoopReverse)
1729 /* there are several tests to determine this */
1731 /* for loop has to be of the form
1732 for ( <sym> = <const1> ;
1733 [<sym> < <const2>] ;
1734 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1736 if (!isLoopCountable (AST_FOR (loop, initExpr),
1737 AST_FOR (loop, condExpr),
1738 AST_FOR (loop, loopExpr),
1739 loopCntrl, init, end))
1742 /* now do some serious checking on the body of the loop
1745 return isConformingBody (loop->left, *loopCntrl, loop->left);
1749 /*-----------------------------------------------------------------*/
1750 /* replLoopSym - replace the loop sym by loop sym -1 */
1751 /*-----------------------------------------------------------------*/
1753 replLoopSym (ast * body, symbol * sym)
1756 if (!body || IS_AST_LINK (body))
1759 if (IS_AST_SYM_VALUE (body))
1762 if (isSymbolEqual (AST_SYMBOL (body), sym))
1766 body->opval.op = '-';
1767 body->left = newAst_VALUE (symbolVal (sym));
1768 body->right = newAst_VALUE (constVal ("1"));
1776 replLoopSym (body->left, sym);
1777 replLoopSym (body->right, sym);
1781 /*-----------------------------------------------------------------*/
1782 /* reverseLoop - do the actual loop reversal */
1783 /*-----------------------------------------------------------------*/
1785 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1789 /* create the following tree
1794 if (sym) goto for_continue ;
1797 /* put it together piece by piece */
1798 rloop = newNode (NULLOP,
1799 createIf (newAst_VALUE (symbolVal (sym)),
1801 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1804 newAst_VALUE (symbolVal (sym)),
1807 replLoopSym (loop->left, sym);
1809 rloop = newNode (NULLOP,
1811 newAst_VALUE (symbolVal (sym)),
1812 newNode ('-', end, init)),
1813 createLabel (AST_FOR (loop, continueLabel),
1817 newNode (SUB_ASSIGN,
1818 newAst_VALUE (symbolVal (sym)),
1819 newAst_VALUE (constVal ("1"))),
1822 return decorateType (rloop);
1826 //#define DEMAND_INTEGER_PROMOTION
1828 #ifdef DEMAND_INTEGER_PROMOTION
1830 /*-----------------------------------------------------------------*/
1831 /* walk a tree looking for the leaves. Add a typecast to the given */
1832 /* type to each value leaf node. */
1833 /*-----------------------------------------------------------------*/
1835 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1837 if (!node || IS_CALLOP(node))
1839 /* WTF? We should never get here. */
1843 if (!node->left && !node->right)
1845 /* We're at a leaf; if it's a value, apply the typecast */
1846 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1848 *parentPtr = decorateType (newNode (CAST,
1849 newAst_LINK (copyLinkChain (type)),
1857 pushTypeCastToLeaves (type, node->left, &(node->left));
1861 pushTypeCastToLeaves (type, node->right, &(node->right));
1868 /*-----------------------------------------------------------------*/
1869 /* Given an assignment operation in a tree, determine if the LHS */
1870 /* (the result) has a different (integer) type than the RHS. */
1871 /* If so, walk the RHS and add a typecast to the type of the LHS */
1872 /* to all leaf nodes. */
1873 /*-----------------------------------------------------------------*/
1875 propAsgType (ast * tree)
1877 #ifdef DEMAND_INTEGER_PROMOTION
1878 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1880 /* Nothing to do here... */
1884 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1886 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1893 /*-----------------------------------------------------------------*/
1894 /* decorateType - compute type for this tree also does type cheking */
1895 /* this is done bottom up, since type have to flow upwards */
1896 /* it also does constant folding, and paramater checking */
1897 /*-----------------------------------------------------------------*/
1899 decorateType (ast * tree)
1907 /* if already has type then do nothing */
1908 if (tree->decorated)
1911 tree->decorated = 1;
1913 /* print the line */
1914 /* if not block & function */
1915 if (tree->type == EX_OP &&
1916 (tree->opval.op != FUNCTION &&
1917 tree->opval.op != BLOCK &&
1918 tree->opval.op != NULLOP))
1920 filename = tree->filename;
1921 lineno = tree->lineno;
1924 /* if any child is an error | this one is an error do nothing */
1925 if (tree->isError ||
1926 (tree->left && tree->left->isError) ||
1927 (tree->right && tree->right->isError))
1930 /*------------------------------------------------------------------*/
1931 /*----------------------------*/
1932 /* leaf has been reached */
1933 /*----------------------------*/
1934 /* if this is of type value */
1935 /* just get the type */
1936 if (tree->type == EX_VALUE)
1939 if (IS_LITERAL (tree->opval.val->etype))
1942 /* if this is a character array then declare it */
1943 if (IS_ARRAY (tree->opval.val->type))
1944 tree->opval.val = stringToSymbol (tree->opval.val);
1946 /* otherwise just copy the type information */
1947 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1948 if (funcInChain (tree->opval.val->type))
1950 tree->hasVargs = tree->opval.val->sym->hasVargs;
1951 tree->args = copyValueChain (tree->opval.val->sym->args);
1956 if (tree->opval.val->sym)
1958 /* if the undefined flag is set then give error message */
1959 if (tree->opval.val->sym->undefined)
1961 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1963 TTYPE (tree) = TETYPE (tree) =
1964 tree->opval.val->type = tree->opval.val->sym->type =
1965 tree->opval.val->etype = tree->opval.val->sym->etype =
1966 copyLinkChain (INTTYPE);
1971 /* if impilicit i.e. struct/union member then no type */
1972 if (tree->opval.val->sym->implicit)
1973 TTYPE (tree) = TETYPE (tree) = NULL;
1978 /* else copy the type */
1979 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1981 /* and mark it as referenced */
1982 tree->opval.val->sym->isref = 1;
1983 /* if this is of type function or function pointer */
1984 if (funcInChain (tree->opval.val->type))
1986 tree->hasVargs = tree->opval.val->sym->hasVargs;
1987 tree->args = copyValueChain (tree->opval.val->sym->args);
1997 /* if type link for the case of cast */
1998 if (tree->type == EX_LINK)
2000 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2007 dtl = decorateType (tree->left);
2008 dtr = decorateType (tree->right);
2010 /* this is to take care of situations
2011 when the tree gets rewritten */
2012 if (dtl != tree->left)
2014 if (dtr != tree->right)
2018 /* depending on type of operator do */
2020 switch (tree->opval.op)
2022 /*------------------------------------------------------------------*/
2023 /*----------------------------*/
2025 /*----------------------------*/
2028 /* determine which is the array & which the index */
2029 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2032 ast *tempTree = tree->left;
2033 tree->left = tree->right;
2034 tree->right = tempTree;
2037 /* first check if this is a array or a pointer */
2038 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2040 werror (E_NEED_ARRAY_PTR, "[]");
2041 goto errorTreeReturn;
2044 /* check if the type of the idx */
2045 if (!IS_INTEGRAL (RTYPE (tree)))
2047 werror (E_IDX_NOT_INT);
2048 goto errorTreeReturn;
2051 /* if the left is an rvalue then error */
2054 werror (E_LVALUE_REQUIRED, "array access");
2055 goto errorTreeReturn;
2058 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2059 if (IS_PTR(LTYPE(tree))) {
2060 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2064 /*------------------------------------------------------------------*/
2065 /*----------------------------*/
2067 /*----------------------------*/
2069 /* if this is not a structure */
2070 if (!IS_STRUCT (LTYPE (tree)))
2072 werror (E_STRUCT_UNION, ".");
2073 goto errorTreeReturn;
2075 TTYPE (tree) = structElemType (LTYPE (tree),
2076 (tree->right->type == EX_VALUE ?
2077 tree->right->opval.val : NULL), &tree->args);
2078 TETYPE (tree) = getSpec (TTYPE (tree));
2081 /*------------------------------------------------------------------*/
2082 /*----------------------------*/
2083 /* struct/union pointer */
2084 /*----------------------------*/
2086 /* if not pointer to a structure */
2087 if (!IS_PTR (LTYPE (tree)))
2089 werror (E_PTR_REQD);
2090 goto errorTreeReturn;
2093 if (!IS_STRUCT (LTYPE (tree)->next))
2095 werror (E_STRUCT_UNION, "->");
2096 goto errorTreeReturn;
2099 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2100 (tree->right->type == EX_VALUE ?
2101 tree->right->opval.val : NULL), &tree->args);
2102 TETYPE (tree) = getSpec (TTYPE (tree));
2105 /*------------------------------------------------------------------*/
2106 /*----------------------------*/
2107 /* ++/-- operation */
2108 /*----------------------------*/
2109 case INC_OP: /* incerement operator unary so left only */
2112 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2113 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2114 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
2115 werror (E_CODE_WRITE, "++/--");
2124 /*------------------------------------------------------------------*/
2125 /*----------------------------*/
2127 /*----------------------------*/
2128 case '&': /* can be unary */
2129 /* if right is NULL then unary operation */
2130 if (tree->right) /* not an unary operation */
2133 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2135 werror (E_BITWISE_OP);
2136 werror (W_CONTINUE, "left & right types are ");
2137 printTypeChain (LTYPE (tree), stderr);
2138 fprintf (stderr, ",");
2139 printTypeChain (RTYPE (tree), stderr);
2140 fprintf (stderr, "\n");
2141 goto errorTreeReturn;
2144 /* if they are both literal */
2145 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2147 tree->type = EX_VALUE;
2148 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2149 valFromType (RETYPE (tree)), '&');
2151 tree->right = tree->left = NULL;
2152 TETYPE (tree) = tree->opval.val->etype;
2153 TTYPE (tree) = tree->opval.val->type;
2157 /* see if this is a GETHBIT operation if yes
2160 ast *otree = optimizeGetHbit (tree);
2163 return decorateType (otree);
2167 // we can't do this because of "(int & 0xff) << 3"
2169 /* if right or left is literal then result of that type */
2170 if (IS_LITERAL (RTYPE (tree)))
2173 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2174 TETYPE (tree) = getSpec (TTYPE (tree));
2175 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2179 if (IS_LITERAL (LTYPE (tree)))
2181 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2182 TETYPE (tree) = getSpec (TTYPE (tree));
2183 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2189 computeType (LTYPE (tree), RTYPE (tree));
2190 TETYPE (tree) = getSpec (TTYPE (tree));
2195 computeType (LTYPE (tree), RTYPE (tree));
2196 TETYPE (tree) = getSpec (TTYPE (tree));
2198 LRVAL (tree) = RRVAL (tree) = 1;
2202 /*------------------------------------------------------------------*/
2203 /*----------------------------*/
2205 /*----------------------------*/
2207 p->class = DECLARATOR;
2208 /* if bit field then error */
2209 if (IS_BITVAR (tree->left->etype))
2211 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2212 goto errorTreeReturn;
2215 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2217 werror (E_ILLEGAL_ADDR, "address of register variable");
2218 goto errorTreeReturn;
2221 if (IS_FUNC (LTYPE (tree)))
2223 werror (E_ILLEGAL_ADDR, "address of function");
2224 goto errorTreeReturn;
2229 werror (E_LVALUE_REQUIRED, "address of");
2230 goto errorTreeReturn;
2232 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2234 DCL_TYPE (p) = CPOINTER;
2235 DCL_PTR_CONST (p) = port->mem.code_ro;
2237 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2238 DCL_TYPE (p) = FPOINTER;
2239 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2240 DCL_TYPE (p) = PPOINTER;
2241 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2242 DCL_TYPE (p) = IPOINTER;
2243 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2244 DCL_TYPE (p) = EEPPOINTER;
2246 DCL_TYPE (p) = POINTER;
2248 if (IS_AST_SYM_VALUE (tree->left))
2250 AST_SYMBOL (tree->left)->addrtaken = 1;
2251 AST_SYMBOL (tree->left)->allocreq = 1;
2254 p->next = LTYPE (tree);
2256 TETYPE (tree) = getSpec (TTYPE (tree));
2257 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2258 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2263 /*------------------------------------------------------------------*/
2264 /*----------------------------*/
2266 /*----------------------------*/
2268 /* if the rewrite succeeds then don't go any furthur */
2270 ast *wtree = optimizeRRCRLC (tree);
2272 return decorateType (wtree);
2274 /*------------------------------------------------------------------*/
2275 /*----------------------------*/
2277 /*----------------------------*/
2279 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2281 werror (E_BITWISE_OP);
2282 werror (W_CONTINUE, "left & right types are ");
2283 printTypeChain (LTYPE (tree), stderr);
2284 fprintf (stderr, ",");
2285 printTypeChain (RTYPE (tree), stderr);
2286 fprintf (stderr, "\n");
2287 goto errorTreeReturn;
2290 /* if they are both literal then */
2291 /* rewrite the tree */
2292 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2294 tree->type = EX_VALUE;
2295 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2296 valFromType (RETYPE (tree)),
2298 tree->right = tree->left = NULL;
2299 TETYPE (tree) = tree->opval.val->etype;
2300 TTYPE (tree) = tree->opval.val->type;
2303 LRVAL (tree) = RRVAL (tree) = 1;
2304 TETYPE (tree) = getSpec (TTYPE (tree) =
2305 computeType (LTYPE (tree),
2308 /*------------------------------------------------------------------*/
2309 /*----------------------------*/
2311 /*----------------------------*/
2313 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2315 werror (E_INVALID_OP, "divide");
2316 goto errorTreeReturn;
2318 /* if they are both literal then */
2319 /* rewrite the tree */
2320 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2322 tree->type = EX_VALUE;
2323 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2324 valFromType (RETYPE (tree)));
2325 tree->right = tree->left = NULL;
2326 TETYPE (tree) = getSpec (TTYPE (tree) =
2327 tree->opval.val->type);
2330 LRVAL (tree) = RRVAL (tree) = 1;
2331 TETYPE (tree) = getSpec (TTYPE (tree) =
2332 computeType (LTYPE (tree),
2336 /*------------------------------------------------------------------*/
2337 /*----------------------------*/
2339 /*----------------------------*/
2341 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2343 werror (E_BITWISE_OP);
2344 werror (W_CONTINUE, "left & right types are ");
2345 printTypeChain (LTYPE (tree), stderr);
2346 fprintf (stderr, ",");
2347 printTypeChain (RTYPE (tree), stderr);
2348 fprintf (stderr, "\n");
2349 goto errorTreeReturn;
2351 /* if they are both literal then */
2352 /* rewrite the tree */
2353 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2355 tree->type = EX_VALUE;
2356 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2357 valFromType (RETYPE (tree)));
2358 tree->right = tree->left = NULL;
2359 TETYPE (tree) = getSpec (TTYPE (tree) =
2360 tree->opval.val->type);
2363 LRVAL (tree) = RRVAL (tree) = 1;
2364 TETYPE (tree) = getSpec (TTYPE (tree) =
2365 computeType (LTYPE (tree),
2369 /*------------------------------------------------------------------*/
2370 /*----------------------------*/
2371 /* address dereference */
2372 /*----------------------------*/
2373 case '*': /* can be unary : if right is null then unary operation */
2376 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2378 werror (E_PTR_REQD);
2379 goto errorTreeReturn;
2384 werror (E_LVALUE_REQUIRED, "pointer deref");
2385 goto errorTreeReturn;
2387 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2388 LTYPE (tree)->next : NULL);
2389 TETYPE (tree) = getSpec (TTYPE (tree));
2390 tree->args = tree->left->args;
2391 tree->hasVargs = tree->left->hasVargs;
2392 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2396 /*------------------------------------------------------------------*/
2397 /*----------------------------*/
2398 /* multiplication */
2399 /*----------------------------*/
2400 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2402 werror (E_INVALID_OP, "multiplication");
2403 goto errorTreeReturn;
2406 /* if they are both literal then */
2407 /* rewrite the tree */
2408 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2410 tree->type = EX_VALUE;
2411 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2412 valFromType (RETYPE (tree)));
2413 tree->right = tree->left = NULL;
2414 TETYPE (tree) = getSpec (TTYPE (tree) =
2415 tree->opval.val->type);
2419 /* if left is a literal exchange left & right */
2420 if (IS_LITERAL (LTYPE (tree)))
2422 ast *tTree = tree->left;
2423 tree->left = tree->right;
2424 tree->right = tTree;
2427 LRVAL (tree) = RRVAL (tree) = 1;
2428 /* promote result to int if left & right are char
2429 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2430 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2431 TETYPE (tree) = getSpec (TTYPE (tree) =
2432 computeType (LTYPE (tree),
2434 SPEC_NOUN(TETYPE(tree)) = V_INT;
2436 TETYPE (tree) = getSpec (TTYPE (tree) =
2437 computeType (LTYPE (tree),
2442 /*------------------------------------------------------------------*/
2443 /*----------------------------*/
2444 /* unary '+' operator */
2445 /*----------------------------*/
2450 if (!IS_INTEGRAL (LTYPE (tree)))
2452 werror (E_UNARY_OP, '+');
2453 goto errorTreeReturn;
2456 /* if left is a literal then do it */
2457 if (IS_LITERAL (LTYPE (tree)))
2459 tree->type = EX_VALUE;
2460 tree->opval.val = valFromType (LETYPE (tree));
2462 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2466 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2470 /*------------------------------------------------------------------*/
2471 /*----------------------------*/
2473 /*----------------------------*/
2475 /* this is not a unary operation */
2476 /* if both pointers then problem */
2477 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2478 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2480 werror (E_PTR_PLUS_PTR);
2481 goto errorTreeReturn;
2484 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2485 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2487 werror (E_PLUS_INVALID, "+");
2488 goto errorTreeReturn;
2491 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2492 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2494 werror (E_PLUS_INVALID, "+");
2495 goto errorTreeReturn;
2497 /* if they are both literal then */
2498 /* rewrite the tree */
2499 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2501 tree->type = EX_VALUE;
2502 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2503 valFromType (RETYPE (tree)));
2504 tree->right = tree->left = NULL;
2505 TETYPE (tree) = getSpec (TTYPE (tree) =
2506 tree->opval.val->type);
2510 /* if the right is a pointer or left is a literal
2511 xchange left & right */
2512 if (IS_ARRAY (RTYPE (tree)) ||
2513 IS_PTR (RTYPE (tree)) ||
2514 IS_LITERAL (LTYPE (tree)))
2516 ast *tTree = tree->left;
2517 tree->left = tree->right;
2518 tree->right = tTree;
2521 LRVAL (tree) = RRVAL (tree) = 1;
2522 /* if the left is a pointer */
2523 if (IS_PTR (LTYPE (tree)))
2524 TETYPE (tree) = getSpec (TTYPE (tree) =
2527 TETYPE (tree) = getSpec (TTYPE (tree) =
2528 computeType (LTYPE (tree),
2532 /*------------------------------------------------------------------*/
2533 /*----------------------------*/
2535 /*----------------------------*/
2536 case '-': /* can be unary */
2537 /* if right is null then unary */
2541 if (!IS_ARITHMETIC (LTYPE (tree)))
2543 werror (E_UNARY_OP, tree->opval.op);
2544 goto errorTreeReturn;
2547 /* if left is a literal then do it */
2548 if (IS_LITERAL (LTYPE (tree)))
2550 tree->type = EX_VALUE;
2551 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2553 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2554 SPEC_USIGN(TETYPE(tree)) = 0;
2558 TTYPE (tree) = LTYPE (tree);
2562 /*------------------------------------------------------------------*/
2563 /*----------------------------*/
2565 /*----------------------------*/
2567 if (!(IS_PTR (LTYPE (tree)) ||
2568 IS_ARRAY (LTYPE (tree)) ||
2569 IS_ARITHMETIC (LTYPE (tree))))
2571 werror (E_PLUS_INVALID, "-");
2572 goto errorTreeReturn;
2575 if (!(IS_PTR (RTYPE (tree)) ||
2576 IS_ARRAY (RTYPE (tree)) ||
2577 IS_ARITHMETIC (RTYPE (tree))))
2579 werror (E_PLUS_INVALID, "-");
2580 goto errorTreeReturn;
2583 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2584 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2585 IS_INTEGRAL (RTYPE (tree))))
2587 werror (E_PLUS_INVALID, "-");
2588 goto errorTreeReturn;
2591 /* if they are both literal then */
2592 /* rewrite the tree */
2593 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2595 tree->type = EX_VALUE;
2596 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2597 valFromType (RETYPE (tree)));
2598 tree->right = tree->left = NULL;
2599 TETYPE (tree) = getSpec (TTYPE (tree) =
2600 tree->opval.val->type);
2604 /* if the left & right are equal then zero */
2605 if (isAstEqual (tree->left, tree->right))
2607 tree->type = EX_VALUE;
2608 tree->left = tree->right = NULL;
2609 tree->opval.val = constVal ("0");
2610 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2614 /* if both of them are pointers or arrays then */
2615 /* the result is going to be an integer */
2616 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2617 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2618 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2620 /* if only the left is a pointer */
2621 /* then result is a pointer */
2622 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2623 TETYPE (tree) = getSpec (TTYPE (tree) =
2626 TETYPE (tree) = getSpec (TTYPE (tree) =
2627 computeType (LTYPE (tree),
2629 LRVAL (tree) = RRVAL (tree) = 1;
2632 /*------------------------------------------------------------------*/
2633 /*----------------------------*/
2635 /*----------------------------*/
2637 /* can be only integral type */
2638 if (!IS_INTEGRAL (LTYPE (tree)))
2640 werror (E_UNARY_OP, tree->opval.op);
2641 goto errorTreeReturn;
2644 /* if left is a literal then do it */
2645 if (IS_LITERAL (LTYPE (tree)))
2647 tree->type = EX_VALUE;
2648 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2650 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2654 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2657 /*------------------------------------------------------------------*/
2658 /*----------------------------*/
2660 /*----------------------------*/
2662 /* can be pointer */
2663 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2664 !IS_PTR (LTYPE (tree)) &&
2665 !IS_ARRAY (LTYPE (tree)))
2667 werror (E_UNARY_OP, tree->opval.op);
2668 goto errorTreeReturn;
2671 /* if left is a literal then do it */
2672 if (IS_LITERAL (LTYPE (tree)))
2674 tree->type = EX_VALUE;
2675 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2677 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2681 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2684 /*------------------------------------------------------------------*/
2685 /*----------------------------*/
2687 /*----------------------------*/
2690 TTYPE (tree) = LTYPE (tree);
2691 TETYPE (tree) = LETYPE (tree);
2695 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2700 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2702 werror (E_SHIFT_OP_INVALID);
2703 werror (W_CONTINUE, "left & right types are ");
2704 printTypeChain (LTYPE (tree), stderr);
2705 fprintf (stderr, ",");
2706 printTypeChain (RTYPE (tree), stderr);
2707 fprintf (stderr, "\n");
2708 goto errorTreeReturn;
2711 /* if they are both literal then */
2712 /* rewrite the tree */
2713 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2715 tree->type = EX_VALUE;
2716 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2717 valFromType (RETYPE (tree)),
2718 (tree->opval.op == LEFT_OP ? 1 : 0));
2719 tree->right = tree->left = NULL;
2720 TETYPE (tree) = getSpec (TTYPE (tree) =
2721 tree->opval.val->type);
2724 /* if only the right side is a literal & we are
2725 shifting more than size of the left operand then zero */
2726 if (IS_LITERAL (RTYPE (tree)) &&
2727 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2728 (getSize (LTYPE (tree)) * 8))
2730 werror (W_SHIFT_CHANGED,
2731 (tree->opval.op == LEFT_OP ? "left" : "right"));
2732 tree->type = EX_VALUE;
2733 tree->left = tree->right = NULL;
2734 tree->opval.val = constVal ("0");
2735 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2738 LRVAL (tree) = RRVAL (tree) = 1;
2739 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2741 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2745 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2749 /*------------------------------------------------------------------*/
2750 /*----------------------------*/
2752 /*----------------------------*/
2753 case CAST: /* change the type */
2754 /* cannot cast to an aggregate type */
2755 if (IS_AGGREGATE (LTYPE (tree)))
2757 werror (E_CAST_ILLEGAL);
2758 goto errorTreeReturn;
2761 /* make sure the type is complete and sane */
2762 checkTypeSanity(LETYPE(tree), "(cast)");
2765 /* if the right is a literal replace the tree */
2766 if (IS_LITERAL (RETYPE (tree))) {
2767 if (!IS_PTR (LTYPE (tree))) {
2768 tree->type = EX_VALUE;
2770 valCastLiteral (LTYPE (tree),
2771 floatFromVal (valFromType (RETYPE (tree))));
2774 TTYPE (tree) = tree->opval.val->type;
2775 tree->values.literalFromCast = 1;
2776 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2777 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2778 sym_link *rest = LTYPE(tree)->next;
2779 werror(W_LITERAL_GENERIC);
2780 TTYPE(tree) = newLink();
2781 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2782 TTYPE(tree)->next = rest;
2783 tree->left->opval.lnk = TTYPE(tree);
2786 TTYPE (tree) = LTYPE (tree);
2790 TTYPE (tree) = LTYPE (tree);
2794 /* if the right is a literal replace the tree */
2795 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2796 tree->type = EX_VALUE;
2798 valCastLiteral (LTYPE (tree),
2799 floatFromVal (valFromType (RETYPE (tree))));
2802 TTYPE (tree) = tree->opval.val->type;
2803 tree->values.literalFromCast = 1;
2805 TTYPE (tree) = LTYPE (tree);
2810 TETYPE (tree) = getSpec (TTYPE (tree));
2814 /*------------------------------------------------------------------*/
2815 /*----------------------------*/
2816 /* logical &&, || */
2817 /*----------------------------*/
2820 /* each must me arithmetic type or be a pointer */
2821 if (!IS_PTR (LTYPE (tree)) &&
2822 !IS_ARRAY (LTYPE (tree)) &&
2823 !IS_INTEGRAL (LTYPE (tree)))
2825 werror (E_COMPARE_OP);
2826 goto errorTreeReturn;
2829 if (!IS_PTR (RTYPE (tree)) &&
2830 !IS_ARRAY (RTYPE (tree)) &&
2831 !IS_INTEGRAL (RTYPE (tree)))
2833 werror (E_COMPARE_OP);
2834 goto errorTreeReturn;
2836 /* if they are both literal then */
2837 /* rewrite the tree */
2838 if (IS_LITERAL (RTYPE (tree)) &&
2839 IS_LITERAL (LTYPE (tree)))
2841 tree->type = EX_VALUE;
2842 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2843 valFromType (RETYPE (tree)),
2845 tree->right = tree->left = NULL;
2846 TETYPE (tree) = getSpec (TTYPE (tree) =
2847 tree->opval.val->type);
2850 LRVAL (tree) = RRVAL (tree) = 1;
2851 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2854 /*------------------------------------------------------------------*/
2855 /*----------------------------*/
2856 /* comparison operators */
2857 /*----------------------------*/
2865 ast *lt = optimizeCompare (tree);
2871 /* if they are pointers they must be castable */
2872 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2874 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2876 werror (E_COMPARE_OP);
2877 fprintf (stderr, "comparing type ");
2878 printTypeChain (LTYPE (tree), stderr);
2879 fprintf (stderr, "to type ");
2880 printTypeChain (RTYPE (tree), stderr);
2881 fprintf (stderr, "\n");
2882 goto errorTreeReturn;
2885 /* else they should be promotable to one another */
2888 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2889 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2891 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2893 werror (E_COMPARE_OP);
2894 fprintf (stderr, "comparing type ");
2895 printTypeChain (LTYPE (tree), stderr);
2896 fprintf (stderr, "to type ");
2897 printTypeChain (RTYPE (tree), stderr);
2898 fprintf (stderr, "\n");
2899 goto errorTreeReturn;
2903 /* if they are both literal then */
2904 /* rewrite the tree */
2905 if (IS_LITERAL (RTYPE (tree)) &&
2906 IS_LITERAL (LTYPE (tree)))
2908 tree->type = EX_VALUE;
2909 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2910 valFromType (RETYPE (tree)),
2912 tree->right = tree->left = NULL;
2913 TETYPE (tree) = getSpec (TTYPE (tree) =
2914 tree->opval.val->type);
2917 LRVAL (tree) = RRVAL (tree) = 1;
2918 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2921 /*------------------------------------------------------------------*/
2922 /*----------------------------*/
2924 /*----------------------------*/
2925 case SIZEOF: /* evaluate wihout code generation */
2926 /* change the type to a integer */
2927 tree->type = EX_VALUE;
2928 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2929 tree->opval.val = constVal (buffer);
2930 tree->right = tree->left = NULL;
2931 TETYPE (tree) = getSpec (TTYPE (tree) =
2932 tree->opval.val->type);
2935 /*------------------------------------------------------------------*/
2936 /*----------------------------*/
2937 /* conditional operator '?' */
2938 /*----------------------------*/
2940 /* the type is value of the colon operator (on the right) */
2941 assert(IS_COLON_OP(tree->right));
2942 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2943 TETYPE (tree) = getSpec (TTYPE (tree));
2947 /* if they don't match we have a problem */
2948 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2950 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2951 goto errorTreeReturn;
2954 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2955 TETYPE (tree) = getSpec (TTYPE (tree));
2959 /*------------------------------------------------------------------*/
2960 /*----------------------------*/
2961 /* assignment operators */
2962 /*----------------------------*/
2965 /* for these it must be both must be integral */
2966 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2967 !IS_ARITHMETIC (RTYPE (tree)))
2969 werror (E_OPS_INTEGRAL);
2970 goto errorTreeReturn;
2973 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2975 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2976 werror (E_CODE_WRITE, " ");
2980 werror (E_LVALUE_REQUIRED, "*= or /=");
2981 goto errorTreeReturn;
2994 /* for these it must be both must be integral */
2995 if (!IS_INTEGRAL (LTYPE (tree)) ||
2996 !IS_INTEGRAL (RTYPE (tree)))
2998 werror (E_OPS_INTEGRAL);
2999 goto errorTreeReturn;
3002 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3004 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3005 werror (E_CODE_WRITE, " ");
3009 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3010 goto errorTreeReturn;
3018 /*------------------------------------------------------------------*/
3019 /*----------------------------*/
3021 /*----------------------------*/
3023 if (!(IS_PTR (LTYPE (tree)) ||
3024 IS_ARITHMETIC (LTYPE (tree))))
3026 werror (E_PLUS_INVALID, "-=");
3027 goto errorTreeReturn;
3030 if (!(IS_PTR (RTYPE (tree)) ||
3031 IS_ARITHMETIC (RTYPE (tree))))
3033 werror (E_PLUS_INVALID, "-=");
3034 goto errorTreeReturn;
3037 TETYPE (tree) = getSpec (TTYPE (tree) =
3038 computeType (LTYPE (tree),
3041 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3042 werror (E_CODE_WRITE, " ");
3046 werror (E_LVALUE_REQUIRED, "-=");
3047 goto errorTreeReturn;
3055 /*------------------------------------------------------------------*/
3056 /*----------------------------*/
3058 /*----------------------------*/
3060 /* this is not a unary operation */
3061 /* if both pointers then problem */
3062 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3064 werror (E_PTR_PLUS_PTR);
3065 goto errorTreeReturn;
3068 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3070 werror (E_PLUS_INVALID, "+=");
3071 goto errorTreeReturn;
3074 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3076 werror (E_PLUS_INVALID, "+=");
3077 goto errorTreeReturn;
3080 TETYPE (tree) = getSpec (TTYPE (tree) =
3081 computeType (LTYPE (tree),
3084 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3085 werror (E_CODE_WRITE, " ");
3089 werror (E_LVALUE_REQUIRED, "+=");
3090 goto errorTreeReturn;
3093 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3094 tree->opval.op = '=';
3100 /*------------------------------------------------------------------*/
3101 /*----------------------------*/
3102 /* straight assignemnt */
3103 /*----------------------------*/
3105 /* cannot be an aggregate */
3106 if (IS_AGGREGATE (LTYPE (tree)))
3108 werror (E_AGGR_ASSIGN);
3109 goto errorTreeReturn;
3112 /* they should either match or be castable */
3113 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3115 werror (E_TYPE_MISMATCH, "assignment", " ");
3116 fprintf (stderr, "type --> '");
3117 printTypeChain (RTYPE (tree), stderr);
3118 fprintf (stderr, "' ");
3119 fprintf (stderr, "assigned to type --> '");
3120 printTypeChain (LTYPE (tree), stderr);
3121 fprintf (stderr, "'\n");
3122 goto errorTreeReturn;
3125 /* if the left side of the tree is of type void
3126 then report error */
3127 if (IS_VOID (LTYPE (tree)))
3129 werror (E_CAST_ZERO);
3130 fprintf (stderr, "type --> '");
3131 printTypeChain (RTYPE (tree), stderr);
3132 fprintf (stderr, "' ");
3133 fprintf (stderr, "assigned to type --> '");
3134 printTypeChain (LTYPE (tree), stderr);
3135 fprintf (stderr, "'\n");
3138 /* extra checks for pointer types */
3139 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
3140 !IS_GENPTR (LTYPE (tree)))
3142 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
3143 werror (W_PTR_ASSIGN);
3146 TETYPE (tree) = getSpec (TTYPE (tree) =
3150 if (!tree->initMode ) {
3151 if (IS_CONSTANT (LETYPE (tree))) {
3152 werror (E_CODE_WRITE, " ");
3157 werror (E_LVALUE_REQUIRED, "=");
3158 goto errorTreeReturn;
3165 /*------------------------------------------------------------------*/
3166 /*----------------------------*/
3167 /* comma operator */
3168 /*----------------------------*/
3170 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3173 /*------------------------------------------------------------------*/
3174 /*----------------------------*/
3176 /*----------------------------*/
3180 if (processParms (tree->left,
3182 tree->right, &parmNumber, TRUE))
3183 goto errorTreeReturn;
3185 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3187 tree->left->args = reverseVal (tree->left->args);
3188 reverseParms (tree->right);
3191 tree->args = tree->left->args;
3192 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3195 /*------------------------------------------------------------------*/
3196 /*----------------------------*/
3197 /* return statement */
3198 /*----------------------------*/
3203 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3205 werror (W_RETURN_MISMATCH);
3206 goto errorTreeReturn;
3209 if (IS_VOID (currFunc->type->next)
3211 !IS_VOID (RTYPE (tree)))
3213 werror (E_FUNC_VOID);
3214 goto errorTreeReturn;
3217 /* if there is going to be a casing required then add it */
3218 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3220 #if 0 && defined DEMAND_INTEGER_PROMOTION
3221 if (IS_INTEGRAL (currFunc->type->next))
3223 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3229 decorateType (newNode (CAST,
3230 newAst_LINK (copyLinkChain (currFunc->type->next)),
3240 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3242 werror (E_VOID_FUNC, currFunc->name);
3243 goto errorTreeReturn;
3246 TTYPE (tree) = TETYPE (tree) = NULL;
3249 /*------------------------------------------------------------------*/
3250 /*----------------------------*/
3251 /* switch statement */
3252 /*----------------------------*/
3254 /* the switch value must be an integer */
3255 if (!IS_INTEGRAL (LTYPE (tree)))
3257 werror (E_SWITCH_NON_INTEGER);
3258 goto errorTreeReturn;
3261 TTYPE (tree) = TETYPE (tree) = NULL;
3264 /*------------------------------------------------------------------*/
3265 /*----------------------------*/
3267 /*----------------------------*/
3269 tree->left = backPatchLabels (tree->left,
3272 TTYPE (tree) = TETYPE (tree) = NULL;
3275 /*------------------------------------------------------------------*/
3276 /*----------------------------*/
3278 /*----------------------------*/
3281 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3282 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3283 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3285 /* if the for loop is reversible then
3286 reverse it otherwise do what we normally
3292 if (isLoopReversible (tree, &sym, &init, &end))
3293 return reverseLoop (tree, sym, init, end);
3295 return decorateType (createFor (AST_FOR (tree, trueLabel),
3296 AST_FOR (tree, continueLabel),
3297 AST_FOR (tree, falseLabel),
3298 AST_FOR (tree, condLabel),
3299 AST_FOR (tree, initExpr),
3300 AST_FOR (tree, condExpr),
3301 AST_FOR (tree, loopExpr),
3305 TTYPE (tree) = TETYPE (tree) = NULL;
3309 /* some error found this tree will be killed */
3311 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3312 tree->opval.op = NULLOP;
3318 /*-----------------------------------------------------------------*/
3319 /* sizeofOp - processes size of operation */
3320 /*-----------------------------------------------------------------*/
3322 sizeofOp (sym_link * type)
3326 /* make sure the type is complete and sane */
3327 checkTypeSanity(type, "(sizeof)");
3329 /* get the size and convert it to character */
3330 sprintf (buff, "%d", getSize (type));
3332 /* now convert into value */
3333 return constVal (buff);
3337 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3338 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3339 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3340 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3341 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3342 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3343 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3345 /*-----------------------------------------------------------------*/
3346 /* backPatchLabels - change and or not operators to flow control */
3347 /*-----------------------------------------------------------------*/
3349 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3355 if (!(IS_ANDORNOT (tree)))
3358 /* if this an and */
3361 static int localLbl = 0;
3364 sprintf (buffer, "_and_%d", localLbl++);
3365 localLabel = newSymbol (buffer, NestLevel);
3367 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3369 /* if left is already a IFX then just change the if true label in that */
3370 if (!IS_IFX (tree->left))
3371 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3373 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3374 /* right is a IFX then just join */
3375 if (IS_IFX (tree->right))
3376 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3378 tree->right = createLabel (localLabel, tree->right);
3379 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3381 return newNode (NULLOP, tree->left, tree->right);
3384 /* if this is an or operation */
3387 static int localLbl = 0;
3390 sprintf (buffer, "_or_%d", localLbl++);
3391 localLabel = newSymbol (buffer, NestLevel);
3393 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3395 /* if left is already a IFX then just change the if true label in that */
3396 if (!IS_IFX (tree->left))
3397 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3399 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3400 /* right is a IFX then just join */
3401 if (IS_IFX (tree->right))
3402 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3404 tree->right = createLabel (localLabel, tree->right);
3405 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3407 return newNode (NULLOP, tree->left, tree->right);
3413 int wasnot = IS_NOT (tree->left);
3414 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3416 /* if the left is already a IFX */
3417 if (!IS_IFX (tree->left))
3418 tree->left = newNode (IFX, tree->left, NULL);
3422 tree->left->trueLabel = trueLabel;
3423 tree->left->falseLabel = falseLabel;
3427 tree->left->trueLabel = falseLabel;
3428 tree->left->falseLabel = trueLabel;
3435 tree->trueLabel = trueLabel;
3436 tree->falseLabel = falseLabel;
3443 /*-----------------------------------------------------------------*/
3444 /* createBlock - create expression tree for block */
3445 /*-----------------------------------------------------------------*/
3447 createBlock (symbol * decl, ast * body)
3451 /* if the block has nothing */
3455 ex = newNode (BLOCK, NULL, body);
3456 ex->values.sym = decl;
3458 ex->right = ex->right;
3464 /*-----------------------------------------------------------------*/
3465 /* createLabel - creates the expression tree for labels */
3466 /*-----------------------------------------------------------------*/
3468 createLabel (symbol * label, ast * stmnt)
3471 char name[SDCC_NAME_MAX + 1];
3474 /* must create fresh symbol if the symbol name */
3475 /* exists in the symbol table, since there can */
3476 /* be a variable with the same name as the labl */
3477 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3478 (csym->level == label->level))
3479 label = newSymbol (label->name, label->level);
3481 /* change the name before putting it in add _ */
3482 sprintf (name, "%s", label->name);
3484 /* put the label in the LabelSymbol table */
3485 /* but first check if a label of the same */
3487 if ((csym = findSym (LabelTab, NULL, name)))
3488 werror (E_DUPLICATE_LABEL, label->name);
3490 addSym (LabelTab, label, name, label->level, 0, 0);
3493 label->key = labelKey++;
3494 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3500 /*-----------------------------------------------------------------*/
3501 /* createCase - generates the parsetree for a case statement */
3502 /*-----------------------------------------------------------------*/
3504 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3506 char caseLbl[SDCC_NAME_MAX + 1];
3510 /* if the switch statement does not exist */
3511 /* then case is out of context */
3514 werror (E_CASE_CONTEXT);
3518 caseVal = decorateType (resolveSymbols (caseVal));
3519 /* if not a constant then error */
3520 if (!IS_LITERAL (caseVal->ftype))
3522 werror (E_CASE_CONSTANT);
3526 /* if not a integer than error */
3527 if (!IS_INTEGRAL (caseVal->ftype))
3529 werror (E_CASE_NON_INTEGER);
3533 /* find the end of the switch values chain */
3534 if (!(val = swStat->values.switchVals.swVals))
3535 swStat->values.switchVals.swVals = caseVal->opval.val;
3538 /* also order the cases according to value */
3540 int cVal = (int) floatFromVal (caseVal->opval.val);
3541 while (val && (int) floatFromVal (val) < cVal)
3547 /* if we reached the end then */
3550 pval->next = caseVal->opval.val;
3554 /* we found a value greater than */
3555 /* the current value we must add this */
3556 /* before the value */
3557 caseVal->opval.val->next = val;
3559 /* if this was the first in chain */
3560 if (swStat->values.switchVals.swVals == val)
3561 swStat->values.switchVals.swVals =
3564 pval->next = caseVal->opval.val;
3569 /* create the case label */
3570 sprintf (caseLbl, "_case_%d_%d",
3571 swStat->values.switchVals.swNum,
3572 (int) floatFromVal (caseVal->opval.val));
3574 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3579 /*-----------------------------------------------------------------*/
3580 /* createDefault - creates the parse tree for the default statement */
3581 /*-----------------------------------------------------------------*/
3583 createDefault (ast * swStat, ast * stmnt)
3585 char defLbl[SDCC_NAME_MAX + 1];
3587 /* if the switch statement does not exist */
3588 /* then case is out of context */
3591 werror (E_CASE_CONTEXT);
3595 /* turn on the default flag */
3596 swStat->values.switchVals.swDefault = 1;
3598 /* create the label */
3599 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3600 return createLabel (newSymbol (defLbl, 0), stmnt);
3603 /*-----------------------------------------------------------------*/
3604 /* createIf - creates the parsetree for the if statement */
3605 /*-----------------------------------------------------------------*/
3607 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3609 static int Lblnum = 0;
3611 symbol *ifTrue, *ifFalse, *ifEnd;
3613 /* if neither exists */
3614 if (!elseBody && !ifBody)
3617 /* create the labels */
3618 sprintf (buffer, "_iffalse_%d", Lblnum);
3619 ifFalse = newSymbol (buffer, NestLevel);
3620 /* if no else body then end == false */
3625 sprintf (buffer, "_ifend_%d", Lblnum);
3626 ifEnd = newSymbol (buffer, NestLevel);
3629 sprintf (buffer, "_iftrue_%d", Lblnum);
3630 ifTrue = newSymbol (buffer, NestLevel);
3634 /* attach the ifTrue label to the top of it body */
3635 ifBody = createLabel (ifTrue, ifBody);
3636 /* attach a goto end to the ifBody if else is present */
3639 ifBody = newNode (NULLOP, ifBody,
3641 newAst_VALUE (symbolVal (ifEnd)),
3643 /* put the elseLabel on the else body */
3644 elseBody = createLabel (ifFalse, elseBody);
3645 /* out the end at the end of the body */
3646 elseBody = newNode (NULLOP,
3648 createLabel (ifEnd, NULL));
3652 ifBody = newNode (NULLOP, ifBody,
3653 createLabel (ifFalse, NULL));
3655 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3656 if (IS_IFX (condAst))
3659 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3661 return newNode (NULLOP, ifTree,
3662 newNode (NULLOP, ifBody, elseBody));
3666 /*-----------------------------------------------------------------*/
3667 /* createDo - creates parse tree for do */
3670 /* _docontinue_n: */
3671 /* condition_expression +-> trueLabel -> _dobody_n */
3673 /* +-> falseLabel-> _dobreak_n */
3675 /*-----------------------------------------------------------------*/
3677 createDo (symbol * trueLabel, symbol * continueLabel,
3678 symbol * falseLabel, ast * condAst, ast * doBody)
3683 /* if the body does not exist then it is simple */
3686 condAst = backPatchLabels (condAst, continueLabel, NULL);
3687 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3688 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3689 doTree->trueLabel = continueLabel;
3690 doTree->falseLabel = NULL;
3694 /* otherwise we have a body */
3695 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3697 /* attach the body label to the top */
3698 doBody = createLabel (trueLabel, doBody);
3699 /* attach the continue label to end of body */
3700 doBody = newNode (NULLOP, doBody,
3701 createLabel (continueLabel, NULL));
3703 /* now put the break label at the end */
3704 if (IS_IFX (condAst))
3707 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3709 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3711 /* putting it together */
3712 return newNode (NULLOP, doBody, doTree);
3715 /*-----------------------------------------------------------------*/
3716 /* createFor - creates parse tree for 'for' statement */
3719 /* condExpr +-> trueLabel -> _forbody_n */
3721 /* +-> falseLabel-> _forbreak_n */
3724 /* _forcontinue_n: */
3726 /* goto _forcond_n ; */
3728 /*-----------------------------------------------------------------*/
3730 createFor (symbol * trueLabel, symbol * continueLabel,
3731 symbol * falseLabel, symbol * condLabel,
3732 ast * initExpr, ast * condExpr, ast * loopExpr,
3737 /* if loopexpression not present then we can generate it */
3738 /* the same way as a while */
3740 return newNode (NULLOP, initExpr,
3741 createWhile (trueLabel, continueLabel,
3742 falseLabel, condExpr, forBody));
3743 /* vanilla for statement */
3744 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3746 if (condExpr && !IS_IFX (condExpr))
3747 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3750 /* attach condition label to condition */
3751 condExpr = createLabel (condLabel, condExpr);
3753 /* attach body label to body */
3754 forBody = createLabel (trueLabel, forBody);
3756 /* attach continue to forLoop expression & attach */
3757 /* goto the forcond @ and of loopExpression */
3758 loopExpr = createLabel (continueLabel,
3762 newAst_VALUE (symbolVal (condLabel)),
3764 /* now start putting them together */
3765 forTree = newNode (NULLOP, initExpr, condExpr);
3766 forTree = newNode (NULLOP, forTree, forBody);
3767 forTree = newNode (NULLOP, forTree, loopExpr);
3768 /* finally add the break label */
3769 forTree = newNode (NULLOP, forTree,
3770 createLabel (falseLabel, NULL));
3774 /*-----------------------------------------------------------------*/
3775 /* createWhile - creates parse tree for while statement */
3776 /* the while statement will be created as follows */
3778 /* _while_continue_n: */
3779 /* condition_expression +-> trueLabel -> _while_boby_n */
3781 /* +-> falseLabel -> _while_break_n */
3782 /* _while_body_n: */
3784 /* goto _while_continue_n */
3785 /* _while_break_n: */
3786 /*-----------------------------------------------------------------*/
3788 createWhile (symbol * trueLabel, symbol * continueLabel,
3789 symbol * falseLabel, ast * condExpr, ast * whileBody)
3793 /* put the continue label */
3794 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3795 condExpr = createLabel (continueLabel, condExpr);
3796 condExpr->lineno = 0;
3798 /* put the body label in front of the body */
3799 whileBody = createLabel (trueLabel, whileBody);
3800 whileBody->lineno = 0;
3801 /* put a jump to continue at the end of the body */
3802 /* and put break label at the end of the body */
3803 whileBody = newNode (NULLOP,
3806 newAst_VALUE (symbolVal (continueLabel)),
3807 createLabel (falseLabel, NULL)));
3809 /* put it all together */
3810 if (IS_IFX (condExpr))
3811 whileTree = condExpr;
3814 whileTree = newNode (IFX, condExpr, NULL);
3815 /* put the true & false labels in place */
3816 whileTree->trueLabel = trueLabel;
3817 whileTree->falseLabel = falseLabel;
3820 return newNode (NULLOP, whileTree, whileBody);
3823 /*-----------------------------------------------------------------*/
3824 /* optimizeGetHbit - get highest order bit of the expression */
3825 /*-----------------------------------------------------------------*/
3827 optimizeGetHbit (ast * tree)
3830 /* if this is not a bit and */
3831 if (!IS_BITAND (tree))
3834 /* will look for tree of the form
3835 ( expr >> ((sizeof expr) -1) ) & 1 */
3836 if (!IS_AST_LIT_VALUE (tree->right))
3839 if (AST_LIT_VALUE (tree->right) != 1)
3842 if (!IS_RIGHT_OP (tree->left))
3845 if (!IS_AST_LIT_VALUE (tree->left->right))
3848 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3849 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3852 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3856 /*-----------------------------------------------------------------*/
3857 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3858 /*-----------------------------------------------------------------*/
3860 optimizeRRCRLC (ast * root)
3862 /* will look for trees of the form
3863 (?expr << 1) | (?expr >> 7) or
3864 (?expr >> 7) | (?expr << 1) will make that
3865 into a RLC : operation ..
3867 (?expr >> 1) | (?expr << 7) or
3868 (?expr << 7) | (?expr >> 1) will make that
3869 into a RRC operation
3870 note : by 7 I mean (number of bits required to hold the
3872 /* if the root operations is not a | operation the not */
3873 if (!IS_BITOR (root))
3876 /* I have to think of a better way to match patterns this sucks */
3877 /* that aside let start looking for the first case : I use a the
3878 negative check a lot to improve the efficiency */
3879 /* (?expr << 1) | (?expr >> 7) */
3880 if (IS_LEFT_OP (root->left) &&
3881 IS_RIGHT_OP (root->right))
3884 if (!SPEC_USIGN (TETYPE (root->left->left)))
3887 if (!IS_AST_LIT_VALUE (root->left->right) ||
3888 !IS_AST_LIT_VALUE (root->right->right))
3891 /* make sure it is the same expression */
3892 if (!isAstEqual (root->left->left,
3896 if (AST_LIT_VALUE (root->left->right) != 1)
3899 if (AST_LIT_VALUE (root->right->right) !=
3900 (getSize (TTYPE (root->left->left)) * 8 - 1))
3903 /* whew got the first case : create the AST */
3904 return newNode (RLC, root->left->left, NULL);
3908 /* check for second case */
3909 /* (?expr >> 7) | (?expr << 1) */
3910 if (IS_LEFT_OP (root->right) &&
3911 IS_RIGHT_OP (root->left))
3914 if (!SPEC_USIGN (TETYPE (root->left->left)))
3917 if (!IS_AST_LIT_VALUE (root->left->right) ||
3918 !IS_AST_LIT_VALUE (root->right->right))
3921 /* make sure it is the same symbol */
3922 if (!isAstEqual (root->left->left,
3926 if (AST_LIT_VALUE (root->right->right) != 1)
3929 if (AST_LIT_VALUE (root->left->right) !=
3930 (getSize (TTYPE (root->left->left)) * 8 - 1))
3933 /* whew got the first case : create the AST */
3934 return newNode (RLC, root->left->left, NULL);
3939 /* third case for RRC */
3940 /* (?symbol >> 1) | (?symbol << 7) */
3941 if (IS_LEFT_OP (root->right) &&
3942 IS_RIGHT_OP (root->left))
3945 if (!SPEC_USIGN (TETYPE (root->left->left)))
3948 if (!IS_AST_LIT_VALUE (root->left->right) ||
3949 !IS_AST_LIT_VALUE (root->right->right))
3952 /* make sure it is the same symbol */
3953 if (!isAstEqual (root->left->left,
3957 if (AST_LIT_VALUE (root->left->right) != 1)
3960 if (AST_LIT_VALUE (root->right->right) !=
3961 (getSize (TTYPE (root->left->left)) * 8 - 1))
3964 /* whew got the first case : create the AST */
3965 return newNode (RRC, root->left->left, NULL);
3969 /* fourth and last case for now */
3970 /* (?symbol << 7) | (?symbol >> 1) */
3971 if (IS_RIGHT_OP (root->right) &&
3972 IS_LEFT_OP (root->left))
3975 if (!SPEC_USIGN (TETYPE (root->left->left)))
3978 if (!IS_AST_LIT_VALUE (root->left->right) ||
3979 !IS_AST_LIT_VALUE (root->right->right))
3982 /* make sure it is the same symbol */
3983 if (!isAstEqual (root->left->left,
3987 if (AST_LIT_VALUE (root->right->right) != 1)
3990 if (AST_LIT_VALUE (root->left->right) !=
3991 (getSize (TTYPE (root->left->left)) * 8 - 1))
3994 /* whew got the first case : create the AST */
3995 return newNode (RRC, root->left->left, NULL);
3999 /* not found return root */
4003 /*-----------------------------------------------------------------*/
4004 /* optimizeCompare - otimizes compares for bit variables */
4005 /*-----------------------------------------------------------------*/
4007 optimizeCompare (ast * root)
4009 ast *optExpr = NULL;
4012 unsigned int litValue;
4014 /* if nothing then return nothing */
4018 /* if not a compare op then do leaves */
4019 if (!IS_COMPARE_OP (root))
4021 root->left = optimizeCompare (root->left);
4022 root->right = optimizeCompare (root->right);
4026 /* if left & right are the same then depending
4027 of the operation do */
4028 if (isAstEqual (root->left, root->right))
4030 switch (root->opval.op)
4035 optExpr = newAst_VALUE (constVal ("0"));
4040 optExpr = newAst_VALUE (constVal ("1"));
4044 return decorateType (optExpr);
4047 vleft = (root->left->type == EX_VALUE ?
4048 root->left->opval.val : NULL);
4050 vright = (root->right->type == EX_VALUE ?
4051 root->right->opval.val : NULL);
4053 /* if left is a BITVAR in BITSPACE */
4054 /* and right is a LITERAL then opt- */
4055 /* imize else do nothing */
4056 if (vleft && vright &&
4057 IS_BITVAR (vleft->etype) &&
4058 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4059 IS_LITERAL (vright->etype))
4062 /* if right side > 1 then comparison may never succeed */
4063 if ((litValue = (int) floatFromVal (vright)) > 1)
4065 werror (W_BAD_COMPARE);
4071 switch (root->opval.op)
4073 case '>': /* bit value greater than 1 cannot be */
4074 werror (W_BAD_COMPARE);
4078 case '<': /* bit value < 1 means 0 */
4080 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4083 case LE_OP: /* bit value <= 1 means no check */
4084 optExpr = newAst_VALUE (vright);
4087 case GE_OP: /* bit value >= 1 means only check for = */
4089 optExpr = newAst_VALUE (vleft);
4094 { /* literal is zero */
4095 switch (root->opval.op)
4097 case '<': /* bit value < 0 cannot be */
4098 werror (W_BAD_COMPARE);
4102 case '>': /* bit value > 0 means 1 */
4104 optExpr = newAst_VALUE (vleft);
4107 case LE_OP: /* bit value <= 0 means no check */
4108 case GE_OP: /* bit value >= 0 means no check */
4109 werror (W_BAD_COMPARE);
4113 case EQ_OP: /* bit == 0 means ! of bit */
4114 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4118 return decorateType (resolveSymbols (optExpr));
4119 } /* end-of-if of BITVAR */
4124 /*-----------------------------------------------------------------*/
4125 /* addSymToBlock : adds the symbol to the first block we find */
4126 /*-----------------------------------------------------------------*/
4128 addSymToBlock (symbol * sym, ast * tree)
4130 /* reached end of tree or a leaf */
4131 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4135 if (IS_AST_OP (tree) &&
4136 tree->opval.op == BLOCK)
4139 symbol *lsym = copySymbol (sym);
4141 lsym->next = AST_VALUES (tree, sym);
4142 AST_VALUES (tree, sym) = lsym;
4146 addSymToBlock (sym, tree->left);
4147 addSymToBlock (sym, tree->right);
4150 /*-----------------------------------------------------------------*/
4151 /* processRegParms - do processing for register parameters */
4152 /*-----------------------------------------------------------------*/
4154 processRegParms (value * args, ast * body)
4158 if (IS_REGPARM (args->etype))
4159 addSymToBlock (args->sym, body);
4164 /*-----------------------------------------------------------------*/
4165 /* resetParmKey - resets the operandkeys for the symbols */
4166 /*-----------------------------------------------------------------*/
4167 DEFSETFUNC (resetParmKey)
4178 /*-----------------------------------------------------------------*/
4179 /* createFunction - This is the key node that calls the iCode for */
4180 /* generating the code for a function. Note code */
4181 /* is generated function by function, later when */
4182 /* add inter-procedural analysis this will change */
4183 /*-----------------------------------------------------------------*/
4185 createFunction (symbol * name, ast * body)
4191 iCode *piCode = NULL;
4193 /* if check function return 0 then some problem */
4194 if (checkFunction (name) == 0)
4197 /* create a dummy block if none exists */
4199 body = newNode (BLOCK, NULL, NULL);
4203 /* check if the function name already in the symbol table */
4204 if ((csym = findSym (SymbolTab, NULL, name->name)))
4207 /* special case for compiler defined functions
4208 we need to add the name to the publics list : this
4209 actually means we are now compiling the compiler
4213 addSet (&publics, name);
4219 allocVariables (name);
4221 name->lastLine = yylineno;
4223 processFuncArgs (currFunc, 0);
4225 /* set the stack pointer */
4226 /* PENDING: check this for the mcs51 */
4227 stackPtr = -port->stack.direction * port->stack.call_overhead;
4228 if (IS_ISR (name->etype))
4229 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4230 if (IS_RENT (name->etype) || options.stackAuto)
4231 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4233 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4235 fetype = getSpec (name->type); /* get the specifier for the function */
4236 /* if this is a reentrant function then */
4237 if (IS_RENT (fetype))
4240 allocParms (name->args); /* allocate the parameters */
4242 /* do processing for parameters that are passed in registers */
4243 processRegParms (name->args, body);
4245 /* set the stack pointer */
4249 /* allocate & autoinit the block variables */
4250 processBlockVars (body, &stack, ALLOCATE);
4252 /* save the stack information */
4253 if (options.useXstack)
4254 name->xstack = SPEC_STAK (fetype) = stack;
4256 name->stack = SPEC_STAK (fetype) = stack;
4258 /* name needs to be mangled */
4259 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4261 body = resolveSymbols (body); /* resolve the symbols */
4262 body = decorateType (body); /* propagateType & do semantic checks */
4264 ex = newAst_VALUE (symbolVal (name)); /* create name */
4265 ex = newNode (FUNCTION, ex, body);
4266 ex->values.args = name->args;
4270 werror (E_FUNC_NO_CODE, name->name);
4274 /* create the node & generate intermediate code */
4276 codeOutFile = code->oFile;
4277 piCode = iCodeFromAst (ex);
4281 werror (E_FUNC_NO_CODE, name->name);
4285 eBBlockFromiCode (piCode);
4287 /* if there are any statics then do them */
4290 GcurMemmap = statsg;
4291 codeOutFile = statsg->oFile;
4292 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4298 /* dealloc the block variables */
4299 processBlockVars (body, &stack, DEALLOCATE);
4300 /* deallocate paramaters */
4301 deallocParms (name->args);
4303 if (IS_RENT (fetype))
4306 /* we are done freeup memory & cleanup */
4311 addSet (&operKeyReset, name);
4312 applyToSet (operKeyReset, resetParmKey);
4315 cdbStructBlock (1, cdbFile);
4317 cleanUpLevel (LabelTab, 0);
4318 cleanUpBlock (StructTab, 1);
4319 cleanUpBlock (TypedefTab, 1);
4321 xstack->syms = NULL;
4322 istack->syms = NULL;
4327 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4328 /*-----------------------------------------------------------------*/
4329 /* ast_print : prints the ast (for debugging purposes) */
4330 /*-----------------------------------------------------------------*/
4332 void ast_print (ast * tree, FILE *outfile, int indent)
4337 /* can print only decorated trees */
4338 if (!tree->decorated) return;
4340 /* if any child is an error | this one is an error do nothing */
4341 if (tree->isError ||
4342 (tree->left && tree->left->isError) ||
4343 (tree->right && tree->right->isError)) {
4344 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4348 /* print the line */
4349 /* if not block & function */
4350 if (tree->type == EX_OP &&
4351 (tree->opval.op != FUNCTION &&
4352 tree->opval.op != BLOCK &&
4353 tree->opval.op != NULLOP)) {
4356 if (tree->opval.op == FUNCTION) {
4357 fprintf(outfile,"FUNCTION (%p) type (",tree);
4358 printTypeChain (tree->ftype,outfile);
4359 fprintf(outfile,")\n");
4360 ast_print(tree->left,outfile,indent+4);
4361 ast_print(tree->right,outfile,indent+4);
4364 if (tree->opval.op == BLOCK) {
4365 symbol *decls = tree->values.sym;
4366 fprintf(outfile,"{\n");
4368 INDENT(indent+4,outfile);
4369 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4370 printTypeChain(decls->type,outfile);
4371 fprintf(outfile,")\n");
4373 decls = decls->next;
4375 ast_print(tree->right,outfile,indent+4);
4376 fprintf(outfile,"}\n");
4379 if (tree->opval.op == NULLOP) {
4380 fprintf(outfile,"\n");
4381 ast_print(tree->left,outfile,indent);
4382 fprintf(outfile,"\n");
4383 ast_print(tree->right,outfile,indent);
4386 INDENT(indent,outfile);
4388 /*------------------------------------------------------------------*/
4389 /*----------------------------*/
4390 /* leaf has been reached */
4391 /*----------------------------*/
4392 /* if this is of type value */
4393 /* just get the type */
4394 if (tree->type == EX_VALUE) {
4396 if (IS_LITERAL (tree->opval.val->etype)) {
4397 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4398 (int) floatFromVal(tree->opval.val),
4399 (int) floatFromVal(tree->opval.val),
4400 floatFromVal(tree->opval.val));
4401 } else if (tree->opval.val->sym) {
4402 /* if the undefined flag is set then give error message */
4403 if (tree->opval.val->sym->undefined) {
4404 fprintf(outfile,"UNDEFINED SYMBOL ");
4406 fprintf(outfile,"SYMBOL ");
4408 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4411 fprintf(outfile," type (");
4412 printTypeChain(tree->ftype,outfile);
4413 fprintf(outfile,")\n");
4415 fprintf(outfile,"\n");
4420 /* if type link for the case of cast */
4421 if (tree->type == EX_LINK) {
4422 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4423 printTypeChain(tree->opval.lnk,outfile);
4424 fprintf(outfile,")\n");
4429 /* depending on type of operator do */
4431 switch (tree->opval.op) {
4432 /*------------------------------------------------------------------*/
4433 /*----------------------------*/
4435 /*----------------------------*/
4437 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4438 printTypeChain(tree->ftype,outfile);
4439 fprintf(outfile,")\n");
4440 ast_print(tree->left,outfile,indent+4);
4441 ast_print(tree->right,outfile,indent+4);
4444 /*------------------------------------------------------------------*/
4445 /*----------------------------*/
4447 /*----------------------------*/
4449 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4450 printTypeChain(tree->ftype,outfile);
4451 fprintf(outfile,")\n");
4452 ast_print(tree->left,outfile,indent+4);
4453 ast_print(tree->right,outfile,indent+4);
4456 /*------------------------------------------------------------------*/
4457 /*----------------------------*/
4458 /* struct/union pointer */
4459 /*----------------------------*/
4461 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4462 printTypeChain(tree->ftype,outfile);
4463 fprintf(outfile,")\n");
4464 ast_print(tree->left,outfile,indent+4);
4465 ast_print(tree->right,outfile,indent+4);
4468 /*------------------------------------------------------------------*/
4469 /*----------------------------*/
4470 /* ++/-- operation */
4471 /*----------------------------*/
4472 case INC_OP: /* incerement operator unary so left only */
4473 fprintf(outfile,"INC_OP (%p) type (",tree);
4474 printTypeChain(tree->ftype,outfile);
4475 fprintf(outfile,")\n");
4476 ast_print(tree->left,outfile,indent+4);
4480 fprintf(outfile,"DEC_OP (%p) type (",tree);
4481 printTypeChain(tree->ftype,outfile);
4482 fprintf(outfile,")\n");
4483 ast_print(tree->left,outfile,indent+4);
4486 /*------------------------------------------------------------------*/
4487 /*----------------------------*/
4489 /*----------------------------*/
4492 fprintf(outfile,"& (%p) type (",tree);
4493 printTypeChain(tree->ftype,outfile);
4494 fprintf(outfile,")\n");
4495 ast_print(tree->left,outfile,indent+4);
4496 ast_print(tree->right,outfile,indent+4);
4498 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4499 printTypeChain(tree->ftype,outfile);
4500 fprintf(outfile,")\n");
4501 ast_print(tree->left,outfile,indent+4);
4502 ast_print(tree->right,outfile,indent+4);
4505 /*----------------------------*/
4507 /*----------------------------*/
4509 fprintf(outfile,"OR (%p) type (",tree);
4510 printTypeChain(tree->ftype,outfile);
4511 fprintf(outfile,")\n");
4512 ast_print(tree->left,outfile,indent+4);
4513 ast_print(tree->right,outfile,indent+4);
4515 /*------------------------------------------------------------------*/
4516 /*----------------------------*/
4518 /*----------------------------*/
4520 fprintf(outfile,"XOR (%p) type (",tree);
4521 printTypeChain(tree->ftype,outfile);
4522 fprintf(outfile,")\n");
4523 ast_print(tree->left,outfile,indent+4);
4524 ast_print(tree->right,outfile,indent+4);
4527 /*------------------------------------------------------------------*/
4528 /*----------------------------*/
4530 /*----------------------------*/
4532 fprintf(outfile,"DIV (%p) type (",tree);
4533 printTypeChain(tree->ftype,outfile);
4534 fprintf(outfile,")\n");
4535 ast_print(tree->left,outfile,indent+4);
4536 ast_print(tree->right,outfile,indent+4);
4538 /*------------------------------------------------------------------*/
4539 /*----------------------------*/
4541 /*----------------------------*/
4543 fprintf(outfile,"MOD (%p) type (",tree);
4544 printTypeChain(tree->ftype,outfile);
4545 fprintf(outfile,")\n");
4546 ast_print(tree->left,outfile,indent+4);
4547 ast_print(tree->right,outfile,indent+4);
4550 /*------------------------------------------------------------------*/
4551 /*----------------------------*/
4552 /* address dereference */
4553 /*----------------------------*/
4554 case '*': /* can be unary : if right is null then unary operation */
4556 fprintf(outfile,"DEREF (%p) type (",tree);
4557 printTypeChain(tree->ftype,outfile);
4558 fprintf(outfile,")\n");
4559 ast_print(tree->left,outfile,indent+4);
4562 /*------------------------------------------------------------------*/
4563 /*----------------------------*/
4564 /* multiplication */
4565 /*----------------------------*/
4566 fprintf(outfile,"MULT (%p) type (",tree);
4567 printTypeChain(tree->ftype,outfile);
4568 fprintf(outfile,")\n");
4569 ast_print(tree->left,outfile,indent+4);
4570 ast_print(tree->right,outfile,indent+4);
4574 /*------------------------------------------------------------------*/
4575 /*----------------------------*/
4576 /* unary '+' operator */
4577 /*----------------------------*/
4581 fprintf(outfile,"UPLUS (%p) type (",tree);
4582 printTypeChain(tree->ftype,outfile);
4583 fprintf(outfile,")\n");
4584 ast_print(tree->left,outfile,indent+4);
4586 /*------------------------------------------------------------------*/
4587 /*----------------------------*/
4589 /*----------------------------*/
4590 fprintf(outfile,"ADD (%p) type (",tree);
4591 printTypeChain(tree->ftype,outfile);
4592 fprintf(outfile,")\n");
4593 ast_print(tree->left,outfile,indent+4);
4594 ast_print(tree->right,outfile,indent+4);
4597 /*------------------------------------------------------------------*/
4598 /*----------------------------*/
4600 /*----------------------------*/
4601 case '-': /* can be unary */
4603 fprintf(outfile,"UMINUS (%p) type (",tree);
4604 printTypeChain(tree->ftype,outfile);
4605 fprintf(outfile,")\n");
4606 ast_print(tree->left,outfile,indent+4);
4608 /*------------------------------------------------------------------*/
4609 /*----------------------------*/
4611 /*----------------------------*/
4612 fprintf(outfile,"SUB (%p) type (",tree);
4613 printTypeChain(tree->ftype,outfile);
4614 fprintf(outfile,")\n");
4615 ast_print(tree->left,outfile,indent+4);
4616 ast_print(tree->right,outfile,indent+4);
4619 /*------------------------------------------------------------------*/
4620 /*----------------------------*/
4622 /*----------------------------*/
4624 fprintf(outfile,"COMPL (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+4);
4629 /*------------------------------------------------------------------*/
4630 /*----------------------------*/
4632 /*----------------------------*/
4634 fprintf(outfile,"NOT (%p) type (",tree);
4635 printTypeChain(tree->ftype,outfile);
4636 fprintf(outfile,")\n");
4637 ast_print(tree->left,outfile,indent+4);
4639 /*------------------------------------------------------------------*/
4640 /*----------------------------*/
4642 /*----------------------------*/
4644 fprintf(outfile,"RRC (%p) type (",tree);
4645 printTypeChain(tree->ftype,outfile);
4646 fprintf(outfile,")\n");
4647 ast_print(tree->left,outfile,indent+4);
4651 fprintf(outfile,"RLC (%p) type (",tree);
4652 printTypeChain(tree->ftype,outfile);
4653 fprintf(outfile,")\n");
4654 ast_print(tree->left,outfile,indent+4);
4657 fprintf(outfile,"GETHBIT (%p) type (",tree);
4658 printTypeChain(tree->ftype,outfile);
4659 fprintf(outfile,")\n");
4660 ast_print(tree->left,outfile,indent+4);
4663 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+4);
4667 ast_print(tree->right,outfile,indent+4);
4670 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4671 printTypeChain(tree->ftype,outfile);
4672 fprintf(outfile,")\n");
4673 ast_print(tree->left,outfile,indent+4);
4674 ast_print(tree->right,outfile,indent+4);
4676 /*------------------------------------------------------------------*/
4677 /*----------------------------*/
4679 /*----------------------------*/
4680 case CAST: /* change the type */
4681 fprintf(outfile,"CAST (%p) type (",tree);
4682 printTypeChain(tree->ftype,outfile);
4683 fprintf(outfile,")\n");
4684 ast_print(tree->right,outfile,indent+4);
4688 fprintf(outfile,"ANDAND (%p) type (",tree);
4689 printTypeChain(tree->ftype,outfile);
4690 fprintf(outfile,")\n");
4691 ast_print(tree->left,outfile,indent+4);
4692 ast_print(tree->right,outfile,indent+4);
4695 fprintf(outfile,"OROR (%p) type (",tree);
4696 printTypeChain(tree->ftype,outfile);
4697 fprintf(outfile,")\n");
4698 ast_print(tree->left,outfile,indent+4);
4699 ast_print(tree->right,outfile,indent+4);
4702 /*------------------------------------------------------------------*/
4703 /*----------------------------*/
4704 /* comparison operators */
4705 /*----------------------------*/
4707 fprintf(outfile,"GT(>) (%p) type (",tree);
4708 printTypeChain(tree->ftype,outfile);
4709 fprintf(outfile,")\n");
4710 ast_print(tree->left,outfile,indent+4);
4711 ast_print(tree->right,outfile,indent+4);
4714 fprintf(outfile,"LT(<) (%p) type (",tree);
4715 printTypeChain(tree->ftype,outfile);
4716 fprintf(outfile,")\n");
4717 ast_print(tree->left,outfile,indent+4);
4718 ast_print(tree->right,outfile,indent+4);
4721 fprintf(outfile,"LE(<=) (%p) type (",tree);
4722 printTypeChain(tree->ftype,outfile);
4723 fprintf(outfile,")\n");
4724 ast_print(tree->left,outfile,indent+4);
4725 ast_print(tree->right,outfile,indent+4);
4728 fprintf(outfile,"GE(>=) (%p) type (",tree);
4729 printTypeChain(tree->ftype,outfile);
4730 fprintf(outfile,")\n");
4731 ast_print(tree->left,outfile,indent+4);
4732 ast_print(tree->right,outfile,indent+4);
4735 fprintf(outfile,"EQ(==) (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+4);
4739 ast_print(tree->right,outfile,indent+4);
4742 fprintf(outfile,"NE(!=) (%p) type (",tree);
4743 printTypeChain(tree->ftype,outfile);
4744 fprintf(outfile,")\n");
4745 ast_print(tree->left,outfile,indent+4);
4746 ast_print(tree->right,outfile,indent+4);
4747 /*------------------------------------------------------------------*/
4748 /*----------------------------*/
4750 /*----------------------------*/
4751 case SIZEOF: /* evaluate wihout code generation */
4752 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4755 /*------------------------------------------------------------------*/
4756 /*----------------------------*/
4757 /* conditional operator '?' */
4758 /*----------------------------*/
4760 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4761 printTypeChain(tree->ftype,outfile);
4762 fprintf(outfile,")\n");
4763 ast_print(tree->left,outfile,indent+4);
4764 ast_print(tree->right,outfile,indent+4);
4767 fprintf(outfile,"COLON(:) (%p) type (",tree);
4768 printTypeChain(tree->ftype,outfile);
4769 fprintf(outfile,")\n");
4770 ast_print(tree->left,outfile,indent+4);
4771 ast_print(tree->right,outfile,indent+4);
4774 /*------------------------------------------------------------------*/
4775 /*----------------------------*/
4776 /* assignment operators */
4777 /*----------------------------*/
4779 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4780 printTypeChain(tree->ftype,outfile);
4781 fprintf(outfile,")\n");
4782 ast_print(tree->left,outfile,indent+4);
4783 ast_print(tree->right,outfile,indent+4);
4786 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4787 printTypeChain(tree->ftype,outfile);
4788 fprintf(outfile,")\n");
4789 ast_print(tree->left,outfile,indent+4);
4790 ast_print(tree->right,outfile,indent+4);
4793 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4794 printTypeChain(tree->ftype,outfile);
4795 fprintf(outfile,")\n");
4796 ast_print(tree->left,outfile,indent+4);
4797 ast_print(tree->right,outfile,indent+4);
4800 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4801 printTypeChain(tree->ftype,outfile);
4802 fprintf(outfile,")\n");
4803 ast_print(tree->left,outfile,indent+4);
4804 ast_print(tree->right,outfile,indent+4);
4807 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4808 printTypeChain(tree->ftype,outfile);
4809 fprintf(outfile,")\n");
4810 ast_print(tree->left,outfile,indent+4);
4811 ast_print(tree->right,outfile,indent+4);
4814 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4815 printTypeChain(tree->ftype,outfile);
4816 fprintf(outfile,")\n");
4817 ast_print(tree->left,outfile,indent+4);
4818 ast_print(tree->right,outfile,indent+4);
4821 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4822 printTypeChain(tree->ftype,outfile);
4823 fprintf(outfile,")\n");
4824 ast_print(tree->left,outfile,indent+4);
4825 ast_print(tree->right,outfile,indent+4);
4827 /*------------------------------------------------------------------*/
4828 /*----------------------------*/
4830 /*----------------------------*/
4832 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4833 printTypeChain(tree->ftype,outfile);
4834 fprintf(outfile,")\n");
4835 ast_print(tree->left,outfile,indent+4);
4836 ast_print(tree->right,outfile,indent+4);
4838 /*------------------------------------------------------------------*/
4839 /*----------------------------*/
4841 /*----------------------------*/
4843 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4844 printTypeChain(tree->ftype,outfile);
4845 fprintf(outfile,")\n");
4846 ast_print(tree->left,outfile,indent+4);
4847 ast_print(tree->right,outfile,indent+4);
4849 /*------------------------------------------------------------------*/
4850 /*----------------------------*/
4851 /* straight assignemnt */
4852 /*----------------------------*/
4854 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4855 printTypeChain(tree->ftype,outfile);
4856 fprintf(outfile,")\n");
4857 ast_print(tree->left,outfile,indent+4);
4858 ast_print(tree->right,outfile,indent+4);
4860 /*------------------------------------------------------------------*/
4861 /*----------------------------*/
4862 /* comma operator */
4863 /*----------------------------*/
4865 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4866 printTypeChain(tree->ftype,outfile);
4867 fprintf(outfile,")\n");
4868 ast_print(tree->left,outfile,indent+4);
4869 ast_print(tree->right,outfile,indent+4);
4871 /*------------------------------------------------------------------*/
4872 /*----------------------------*/
4874 /*----------------------------*/
4877 fprintf(outfile,"CALL (%p) type (",tree);
4878 printTypeChain(tree->ftype,outfile);
4879 fprintf(outfile,")\n");
4880 ast_print(tree->left,outfile,indent+4);
4881 ast_print(tree->right,outfile,indent+4);
4884 fprintf(outfile,"PARM ");
4885 ast_print(tree->left,outfile,indent+4);
4886 if (tree->right && !IS_AST_PARAM(tree->right)) {
4887 fprintf(outfile,"PARM ");
4888 ast_print(tree->right,outfile,indent+4);
4891 /*------------------------------------------------------------------*/
4892 /*----------------------------*/
4893 /* return statement */
4894 /*----------------------------*/
4896 fprintf(outfile,"RETURN (%p) type (",tree);
4897 printTypeChain(tree->right->ftype,outfile);
4898 fprintf(outfile,")\n");
4899 ast_print(tree->right,outfile,indent+4);
4901 /*------------------------------------------------------------------*/
4902 /*----------------------------*/
4903 /* label statement */
4904 /*----------------------------*/
4906 fprintf(outfile,"LABEL (%p)",tree);
4907 ast_print(tree->left,outfile,indent+4);
4908 ast_print(tree->right,outfile,indent);
4910 /*------------------------------------------------------------------*/
4911 /*----------------------------*/
4912 /* switch statement */
4913 /*----------------------------*/
4917 fprintf(outfile,"SWITCH (%p) ",tree);
4918 ast_print(tree->left,outfile,0);
4919 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4920 INDENT(indent+4,outfile);
4921 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4922 (int) floatFromVal(val),
4923 tree->values.switchVals.swNum,
4924 (int) floatFromVal(val));
4926 ast_print(tree->right,outfile,indent);
4929 /*------------------------------------------------------------------*/
4930 /*----------------------------*/
4932 /*----------------------------*/
4934 ast_print(tree->left,outfile,indent);
4935 INDENT(indent,outfile);
4936 fprintf(outfile,"IF (%p) \n",tree);
4937 if (tree->trueLabel) {
4938 INDENT(indent,outfile);
4939 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4941 if (tree->falseLabel) {
4942 INDENT(indent,outfile);
4943 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4945 ast_print(tree->right,outfile,indent);
4947 /*------------------------------------------------------------------*/
4948 /*----------------------------*/
4950 /*----------------------------*/
4952 fprintf(outfile,"FOR (%p) \n",tree);
4953 if (AST_FOR( tree, initExpr)) {
4954 INDENT(indent+4,outfile);
4955 fprintf(outfile,"INIT EXPR ");
4956 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4958 if (AST_FOR( tree, condExpr)) {
4959 INDENT(indent+4,outfile);
4960 fprintf(outfile,"COND EXPR ");
4961 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4963 if (AST_FOR( tree, loopExpr)) {
4964 INDENT(indent+4,outfile);
4965 fprintf(outfile,"LOOP EXPR ");
4966 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4968 fprintf(outfile,"FOR LOOP BODY \n");
4969 ast_print(tree->left,outfile,indent+4);
4978 ast_print(t,stdout,1);