1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 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 /*-----------------------------------------------------------------*/
73 newAst_ (unsigned type)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
90 newAst_VALUE (value * val)
92 ast *ex = newAst_ (EX_VALUE);
98 newAst_OP (unsigned op)
100 ast *ex = newAst_ (EX_OP);
106 newAst_LINK (sym_link * val)
108 ast *ex = newAst_ (EX_LINK);
114 newAst_STMNT (unsigned val)
116 ast *ex = newAst_ (EX_STMNT);
117 ex->opval.stmnt = val;
121 /*-----------------------------------------------------------------*/
122 /* newNode - creates a new node */
123 /*-----------------------------------------------------------------*/
125 newNode (long op, ast * left, ast * right)
136 /*-----------------------------------------------------------------*/
137 /* newIfxNode - creates a new Ifx Node */
138 /*-----------------------------------------------------------------*/
140 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
144 /* if this is a literal then we already know the result */
145 if (condAst->etype && IS_LITERAL (condAst->etype))
147 /* then depending on the expression value */
148 if (floatFromVal (condAst->opval.val))
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (trueLabel)),
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (falseLabel)),
159 ifxNode = newNode (IFX, condAst, NULL);
160 ifxNode->trueLabel = trueLabel;
161 ifxNode->falseLabel = falseLabel;
167 /*-----------------------------------------------------------------*/
168 /* copyAstValues - copies value portion of ast if needed */
169 /*-----------------------------------------------------------------*/
171 copyAstValues (ast * dest, ast * src)
173 switch (src->opval.op)
176 dest->values.sym = copySymbolChain (src->values.sym);
180 dest->values.switchVals.swVals =
181 copyValue (src->values.switchVals.swVals);
182 dest->values.switchVals.swDefault =
183 src->values.switchVals.swDefault;
184 dest->values.switchVals.swNum =
185 src->values.switchVals.swNum;
189 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
190 strcpy (dest->values.inlineasm, src->values.inlineasm);
194 dest->values.constlist = copyLiteralList(src->values.constlist);
198 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
199 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
200 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
201 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
202 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
203 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
204 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
209 /*-----------------------------------------------------------------*/
210 /* copyAst - makes a copy of a given astession */
211 /*-----------------------------------------------------------------*/
220 dest = Safe_alloc ( sizeof (ast));
222 dest->type = src->type;
223 dest->lineno = src->lineno;
224 dest->level = src->level;
225 dest->funcName = src->funcName;
228 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
230 /* if this is a leaf */
232 if (src->type == EX_VALUE)
234 dest->opval.val = copyValue (src->opval.val);
239 if (src->type == EX_LINK)
241 dest->opval.lnk = copyLinkChain (src->opval.lnk);
245 dest->opval.op = src->opval.op;
247 /* if this is a node that has special values */
248 copyAstValues (dest, src);
250 dest->trueLabel = copySymbol (src->trueLabel);
251 dest->falseLabel = copySymbol (src->falseLabel);
252 dest->left = copyAst (src->left);
253 dest->right = copyAst (src->right);
259 /*-----------------------------------------------------------------*/
260 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
261 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
262 /*-----------------------------------------------------------------*/
263 ast *removeIncDecOps (ast * tree) {
265 // traverse the tree and remove inc/dec ops
270 if (tree->type == EX_OP &&
271 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
278 tree->left=removeIncDecOps(tree->left);
279 tree->right=removeIncDecOps(tree->right);
284 /*-----------------------------------------------------------------*/
285 /* hasSEFcalls - returns TRUE if tree has a function call */
286 /*-----------------------------------------------------------------*/
288 hasSEFcalls (ast * tree)
293 if (tree->type == EX_OP &&
294 (tree->opval.op == CALL ||
295 tree->opval.op == PCALL ||
296 tree->opval.op == '=' ||
297 tree->opval.op == INC_OP ||
298 tree->opval.op == DEC_OP))
301 return (hasSEFcalls (tree->left) |
302 hasSEFcalls (tree->right));
305 /*-----------------------------------------------------------------*/
306 /* isAstEqual - compares two asts & returns 1 if they are equal */
307 /*-----------------------------------------------------------------*/
309 isAstEqual (ast * t1, ast * t2)
318 if (t1->type != t2->type)
324 if (t1->opval.op != t2->opval.op)
326 return (isAstEqual (t1->left, t2->left) &&
327 isAstEqual (t1->right, t2->right));
331 if (t1->opval.val->sym)
333 if (!t2->opval.val->sym)
336 return isSymbolEqual (t1->opval.val->sym,
341 if (t2->opval.val->sym)
344 return (floatFromVal (t1->opval.val) ==
345 floatFromVal (t2->opval.val));
349 /* only compare these two types */
357 /*-----------------------------------------------------------------*/
358 /* resolveSymbols - resolve symbols from the symbol table */
359 /*-----------------------------------------------------------------*/
361 resolveSymbols (ast * tree)
363 /* walk the entire tree and check for values */
364 /* with symbols if we find one then replace */
365 /* symbol with that from the symbol table */
371 /* if not block & function */
372 if (tree->type == EX_OP &&
373 (tree->opval.op != FUNCTION &&
374 tree->opval.op != BLOCK &&
375 tree->opval.op != NULLOP))
377 filename = tree->filename;
378 lineno = tree->lineno;
381 /* make sure we resolve the true & false labels for ifx */
382 if (tree->type == EX_OP && tree->opval.op == IFX)
388 if ((csym = findSym (LabelTab, tree->trueLabel,
389 tree->trueLabel->name)))
390 tree->trueLabel = csym;
392 werror (E_LABEL_UNDEF, tree->trueLabel->name);
395 if (tree->falseLabel)
397 if ((csym = findSym (LabelTab,
399 tree->falseLabel->name)))
400 tree->falseLabel = csym;
402 werror (E_LABEL_UNDEF, tree->falseLabel->name);
407 /* if this is a label resolve it from the labelTab */
408 if (IS_AST_VALUE (tree) &&
409 tree->opval.val->sym &&
410 tree->opval.val->sym->islbl)
413 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
414 tree->opval.val->sym->name);
417 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
419 tree->opval.val->sym = csym;
421 goto resolveChildren;
424 /* do only for leafs */
425 if (IS_AST_VALUE (tree) &&
426 tree->opval.val->sym &&
427 !tree->opval.val->sym->implicit)
430 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
432 /* if found in the symbol table & they r not the same */
433 if (csym && tree->opval.val->sym != csym)
435 tree->opval.val->sym = csym;
436 tree->opval.val->type = csym->type;
437 tree->opval.val->etype = csym->etype;
440 /* if not found in the symbol table */
441 /* mark it as undefined assume it is */
442 /* an integer in data space */
443 if (!csym && !tree->opval.val->sym->implicit)
446 /* if this is a function name then */
447 /* mark it as returning an int */
450 tree->opval.val->sym->type = newLink ();
451 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
452 tree->opval.val->sym->type->next =
453 tree->opval.val->sym->etype = newIntLink ();
454 tree->opval.val->etype = tree->opval.val->etype;
455 tree->opval.val->type = tree->opval.val->sym->type;
456 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
457 allocVariables (tree->opval.val->sym);
461 tree->opval.val->sym->undefined = 1;
462 tree->opval.val->type =
463 tree->opval.val->etype = newIntLink ();
464 tree->opval.val->sym->type =
465 tree->opval.val->sym->etype = newIntLink ();
471 resolveSymbols (tree->left);
472 resolveSymbols (tree->right);
477 /*-----------------------------------------------------------------*/
478 /* setAstLineno - walks a ast tree & sets the line number */
479 /*-----------------------------------------------------------------*/
480 int setAstLineno (ast * tree, int lineno)
485 tree->lineno = lineno;
486 setAstLineno (tree->left, lineno);
487 setAstLineno (tree->right, lineno);
491 /*-----------------------------------------------------------------*/
492 /* funcOfType :- function of type with name */
493 /*-----------------------------------------------------------------*/
495 funcOfType (char *name, sym_link * type, sym_link * argType,
499 /* create the symbol */
500 sym = newSymbol (name, 0);
502 /* setup return value */
503 sym->type = newLink ();
504 DCL_TYPE (sym->type) = FUNCTION;
505 sym->type->next = copyLinkChain (type);
506 sym->etype = getSpec (sym->type);
507 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
509 /* if arguments required */
513 args = FUNC_ARGS(sym->type) = newValue ();
517 args->type = copyLinkChain (argType);
518 args->etype = getSpec (args->type);
519 SPEC_EXTR(args->etype)=1;
522 args = args->next = newValue ();
529 allocVariables (sym);
534 /*-----------------------------------------------------------------*/
535 /* funcOfTypeVarg :- function of type with name and argtype */
536 /*-----------------------------------------------------------------*/
538 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
543 /* create the symbol */
544 sym = newSymbol (name, 0);
546 /* setup return value */
547 sym->type = newLink ();
548 DCL_TYPE (sym->type) = FUNCTION;
549 sym->type->next = typeFromStr(rtype);
550 sym->etype = getSpec (sym->type);
552 /* if arguments required */
555 args = FUNC_ARGS(sym->type) = newValue ();
557 for ( i = 0 ; i < nArgs ; i++ ) {
558 args->type = typeFromStr(atypes[i]);
559 args->etype = getSpec (args->type);
560 SPEC_EXTR(args->etype)=1;
561 if ((i + 1) == nArgs) break;
562 args = args->next = newValue ();
569 allocVariables (sym);
574 /*-----------------------------------------------------------------*/
575 /* reverseParms - will reverse a parameter tree */
576 /*-----------------------------------------------------------------*/
578 reverseParms (ast * ptree)
584 /* top down if we find a nonParm tree then quit */
585 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
588 ptree->left = ptree->right;
589 ptree->right = ttree;
590 reverseParms (ptree->left);
591 reverseParms (ptree->right);
597 /*-----------------------------------------------------------------*/
598 /* processParms - makes sure the parameters are okay and do some */
599 /* processing with them */
600 /*-----------------------------------------------------------------*/
602 processParms (ast * func,
605 int *parmNumber, // unused, although updated
608 /* if none of them exist */
609 if (!defParm && !actParm)
613 if (getenv("DEBUG_SANITY")) {
614 fprintf (stderr, "processParms: %s ", defParm->name);
616 /* make sure the type is complete and sane */
617 checkTypeSanity(defParm->etype, defParm->name);
620 /* if the function is being called via a pointer & */
621 /* it has not been defined a reentrant then we cannot */
622 /* have parameters */
623 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
625 werror (W_NONRENT_ARGS);
629 /* if defined parameters ended but actual parameters */
630 /* exist and this is not defined as a variable arg */
631 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
633 werror (E_TOO_MANY_PARMS);
637 /* if defined parameters present but no actual parameters */
638 if (defParm && !actParm)
640 werror (E_TOO_FEW_PARMS);
644 if (IS_VOID(actParm->ftype)) {
645 werror (E_VOID_VALUE_USED);
649 /* If this is a varargs function... */
650 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
655 if (IS_CAST_OP (actParm)
656 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
658 /* Parameter was explicitly typecast; don't touch it. */
662 ftype = actParm->ftype;
664 /* If it's a small integer, upcast to int. */
665 if (IS_INTEGRAL (ftype)
666 && (getSize (ftype) < (unsigned) INTSIZE))
668 newType = newAst_LINK(INTTYPE);
671 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
673 newType = newAst_LINK (copyLinkChain(ftype));
674 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
677 if (IS_AGGREGATE (ftype))
679 newType = newAst_LINK (copyLinkChain (ftype));
680 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
684 /* cast required; change this op to a cast. */
685 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
687 actParm->type = EX_OP;
688 actParm->opval.op = CAST;
689 actParm->left = newType;
690 actParm->right = parmCopy;
691 decorateType (actParm);
693 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
695 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
696 processParms (func, NULL, actParm->right, parmNumber, rightmost));
701 /* if defined parameters ended but actual has not & */
703 if (!defParm && actParm &&
704 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
707 resolveSymbols (actParm);
708 /* if this is a PARAM node then match left & right */
709 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
711 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
712 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
716 /* If we have found a value node by following only right-hand links,
717 * then we know that there are no more values after us.
719 * Therefore, if there are more defined parameters, the caller didn't
722 if (rightmost && defParm->next)
724 werror (E_TOO_FEW_PARMS);
729 /* the parameter type must be at least castable */
730 if (compareType (defParm->type, actParm->ftype) == 0) {
731 werror (E_INCOMPAT_TYPES);
732 printFromToType (actParm->ftype, defParm->type);
736 /* if the parameter is castable then add the cast */
737 if (compareType (defParm->type, actParm->ftype) < 0)
739 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
741 /* now change the current one to a cast */
742 actParm->type = EX_OP;
743 actParm->opval.op = CAST;
744 actParm->left = newAst_LINK (defParm->type);
745 actParm->right = pTree;
746 actParm->etype = defParm->etype;
747 actParm->ftype = defParm->type;
748 actParm->decorated=0; /* force typechecking */
749 decorateType (actParm);
752 /* make a copy and change the regparm type to the defined parm */
753 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
754 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
755 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
759 /*-----------------------------------------------------------------*/
760 /* createIvalType - generates ival for basic types */
761 /*-----------------------------------------------------------------*/
763 createIvalType (ast * sym, sym_link * type, initList * ilist)
767 /* if initList is deep */
768 if (ilist->type == INIT_DEEP)
769 ilist = ilist->init.deep;
771 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
772 return decorateType (newNode ('=', sym, iExpr));
775 /*-----------------------------------------------------------------*/
776 /* createIvalStruct - generates initial value for structures */
777 /*-----------------------------------------------------------------*/
779 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
786 sflds = SPEC_STRUCT (type)->fields;
787 if (ilist->type != INIT_DEEP)
789 werror (E_INIT_STRUCT, "");
793 iloop = ilist->init.deep;
795 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
797 /* if we have come to end */
801 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
802 lAst = decorateType (resolveSymbols (lAst));
803 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
807 werror (W_EXCESS_INITIALIZERS, "struct",
808 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
815 /*-----------------------------------------------------------------*/
816 /* createIvalArray - generates code for array initialization */
817 /*-----------------------------------------------------------------*/
819 createIvalArray (ast * sym, sym_link * type, initList * ilist)
823 int lcnt = 0, size = 0;
824 literalList *literalL;
826 /* take care of the special case */
827 /* array of characters can be init */
829 if (IS_CHAR (type->next))
830 if ((rast = createIvalCharPtr (sym,
832 decorateType (resolveSymbols (list2expr (ilist))))))
834 return decorateType (resolveSymbols (rast));
836 /* not the special case */
837 if (ilist->type != INIT_DEEP)
839 werror (E_INIT_STRUCT, "");
843 iloop = ilist->init.deep;
844 lcnt = DCL_ELEM (type);
846 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
850 aSym = decorateType (resolveSymbols(sym));
852 rast = newNode(ARRAYINIT, aSym, NULL);
853 rast->values.constlist = literalL;
855 // Make sure size is set to length of initializer list.
862 if (lcnt && size > lcnt)
864 // Array size was specified, and we have more initializers than needed.
865 char *name=sym->opval.val->sym->name;
866 int lineno=sym->opval.val->sym->lineDef;
868 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
877 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
878 aSym = decorateType (resolveSymbols (aSym));
879 rast = createIval (aSym, type->next, iloop, rast);
880 iloop = (iloop ? iloop->next : NULL);
886 /* no of elements given and we */
887 /* have generated for all of them */
890 // there has to be a better way
891 char *name=sym->opval.val->sym->name;
892 int lineno=sym->opval.val->sym->lineDef;
893 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
900 /* if we have not been given a size */
901 if (!DCL_ELEM (type))
903 DCL_ELEM (type) = size;
906 return decorateType (resolveSymbols (rast));
910 /*-----------------------------------------------------------------*/
911 /* createIvalCharPtr - generates initial values for char pointers */
912 /*-----------------------------------------------------------------*/
914 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
918 /* if this is a pointer & right is a literal array then */
919 /* just assignment will do */
920 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
921 SPEC_SCLS (iexpr->etype) == S_CODE)
922 && IS_ARRAY (iexpr->ftype)))
923 return newNode ('=', sym, iexpr);
925 /* left side is an array so we have to assign each */
927 if ((IS_LITERAL (iexpr->etype) ||
928 SPEC_SCLS (iexpr->etype) == S_CODE)
929 && IS_ARRAY (iexpr->ftype))
931 /* for each character generate an assignment */
932 /* to the array element */
933 char *s = SPEC_CVAL (iexpr->etype).v_char;
938 rast = newNode (NULLOP,
942 newAst_VALUE (valueFromLit ((float) i))),
943 newAst_VALUE (valueFromLit (*s))));
947 rast = newNode (NULLOP,
951 newAst_VALUE (valueFromLit ((float) i))),
952 newAst_VALUE (valueFromLit (*s))));
954 // now we don't need iexpr's symbol anymore
956 symbol *sym=AST_SYMBOL(iexpr);
957 memmap *segment=SPEC_OCLS(sym->etype);
958 deleteSetItem(&segment->syms, sym);
960 return decorateType (resolveSymbols (rast));
966 /*-----------------------------------------------------------------*/
967 /* createIvalPtr - generates initial value for pointers */
968 /*-----------------------------------------------------------------*/
970 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
976 if (ilist->type == INIT_DEEP)
977 ilist = ilist->init.deep;
979 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
981 /* if character pointer */
982 if (IS_CHAR (type->next))
983 if ((rast = createIvalCharPtr (sym, type, iexpr)))
986 return newNode ('=', sym, iexpr);
989 /*-----------------------------------------------------------------*/
990 /* createIval - generates code for initial value */
991 /*-----------------------------------------------------------------*/
993 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1000 /* if structure then */
1001 if (IS_STRUCT (type))
1002 rast = createIvalStruct (sym, type, ilist);
1004 /* if this is a pointer */
1006 rast = createIvalPtr (sym, type, ilist);
1008 /* if this is an array */
1009 if (IS_ARRAY (type))
1010 rast = createIvalArray (sym, type, ilist);
1012 /* if type is SPECIFIER */
1014 rast = createIvalType (sym, type, ilist);
1017 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1019 return decorateType (resolveSymbols (rast));
1022 /*-----------------------------------------------------------------*/
1023 /* initAggregates - initialises aggregate variables with initv */
1024 /*-----------------------------------------------------------------*/
1025 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1026 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1029 /*-----------------------------------------------------------------*/
1030 /* gatherAutoInit - creates assignment expressions for initial */
1032 /*-----------------------------------------------------------------*/
1034 gatherAutoInit (symbol * autoChain)
1041 for (sym = autoChain; sym; sym = sym->next)
1044 /* resolve the symbols in the ival */
1046 resolveIvalSym (sym->ival);
1048 /* if this is a static variable & has an */
1049 /* initial value the code needs to be lifted */
1050 /* here to the main portion since they can be */
1051 /* initialised only once at the start */
1052 if (IS_STATIC (sym->etype) && sym->ival &&
1053 SPEC_SCLS (sym->etype) != S_CODE)
1057 /* insert the symbol into the symbol table */
1058 /* with level = 0 & name = rname */
1059 newSym = copySymbol (sym);
1060 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1062 /* now lift the code to main */
1063 if (IS_AGGREGATE (sym->type)) {
1064 work = initAggregates (sym, sym->ival, NULL);
1066 if (getNelements(sym->type, sym->ival)>1) {
1067 werror (W_EXCESS_INITIALIZERS, "scalar",
1068 sym->name, sym->lineDef);
1070 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1071 list2expr (sym->ival));
1074 setAstLineno (work, sym->lineDef);
1078 staticAutos = newNode (NULLOP, staticAutos, work);
1085 /* if there is an initial value */
1086 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1088 if (IS_AGGREGATE (sym->type)) {
1089 work = initAggregates (sym, sym->ival, NULL);
1091 if (getNelements(sym->type, sym->ival)>1) {
1092 werror (W_EXCESS_INITIALIZERS, "scalar",
1093 sym->name, sym->lineDef);
1095 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1096 list2expr (sym->ival));
1099 setAstLineno (work, sym->lineDef);
1102 init = newNode (NULLOP, init, work);
1111 /*-----------------------------------------------------------------*/
1112 /* stringToSymbol - creates a symbol from a literal string */
1113 /*-----------------------------------------------------------------*/
1115 stringToSymbol (value * val)
1117 char name[SDCC_NAME_MAX + 1];
1118 static int charLbl = 0;
1121 sprintf (name, "_str_%d", charLbl++);
1122 sym = newSymbol (name, 0); /* make it @ level 0 */
1123 strcpy (sym->rname, name);
1125 /* copy the type from the value passed */
1126 sym->type = copyLinkChain (val->type);
1127 sym->etype = getSpec (sym->type);
1128 /* change to storage class & output class */
1129 SPEC_SCLS (sym->etype) = S_CODE;
1130 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1131 SPEC_STAT (sym->etype) = 1;
1132 /* make the level & block = 0 */
1133 sym->block = sym->level = 0;
1135 /* create an ival */
1136 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1141 allocVariables (sym);
1144 return symbolVal (sym);
1148 /*-----------------------------------------------------------------*/
1149 /* processBlockVars - will go thru the ast looking for block if */
1150 /* a block is found then will allocate the syms */
1151 /* will also gather the auto inits present */
1152 /*-----------------------------------------------------------------*/
1154 processBlockVars (ast * tree, int *stack, int action)
1159 /* if this is a block */
1160 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1164 if (action == ALLOCATE)
1166 *stack += allocVariables (tree->values.sym);
1167 autoInit = gatherAutoInit (tree->values.sym);
1169 /* if there are auto inits then do them */
1171 tree->left = newNode (NULLOP, autoInit, tree->left);
1173 else /* action is deallocate */
1174 deallocLocal (tree->values.sym);
1177 processBlockVars (tree->left, stack, action);
1178 processBlockVars (tree->right, stack, action);
1182 /*-------------------------------------------------------------*/
1183 /* constExprTree - returns TRUE if this tree is a constant */
1185 /*-------------------------------------------------------------*/
1186 bool constExprTree (ast *cexpr) {
1192 cexpr = decorateType (resolveSymbols (cexpr));
1194 switch (cexpr->type)
1197 if (IS_AST_LIT_VALUE(cexpr)) {
1198 // this is a literal
1201 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1202 // a function's address will never change
1205 if (IS_AST_SYM_VALUE(cexpr) &&
1206 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1207 // a symbol in code space will never change
1208 // This is only for the 'char *s="hallo"' case and will have to leave
1213 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1214 "unexpected link in expression tree\n");
1217 if (cexpr->opval.op==ARRAYINIT) {
1218 // this is a list of literals
1221 if (cexpr->opval.op=='=') {
1222 return constExprTree(cexpr->right);
1224 if (cexpr->opval.op==CAST) {
1225 // jwk: cast ignored, maybe we should throw a warning here
1226 return constExprTree(cexpr->right);
1228 if (cexpr->opval.op=='&') {
1231 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1234 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1241 /*-----------------------------------------------------------------*/
1242 /* constExprValue - returns the value of a constant expression */
1243 /* or NULL if it is not a constant expression */
1244 /*-----------------------------------------------------------------*/
1246 constExprValue (ast * cexpr, int check)
1248 cexpr = decorateType (resolveSymbols (cexpr));
1250 /* if this is not a constant then */
1251 if (!IS_LITERAL (cexpr->ftype))
1253 /* then check if this is a literal array
1255 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1256 SPEC_CVAL (cexpr->etype).v_char &&
1257 IS_ARRAY (cexpr->ftype))
1259 value *val = valFromType (cexpr->ftype);
1260 SPEC_SCLS (val->etype) = S_LITERAL;
1261 val->sym = cexpr->opval.val->sym;
1262 val->sym->type = copyLinkChain (cexpr->ftype);
1263 val->sym->etype = getSpec (val->sym->type);
1264 strcpy (val->name, cexpr->opval.val->sym->rname);
1268 /* if we are casting a literal value then */
1269 if (IS_AST_OP (cexpr) &&
1270 cexpr->opval.op == CAST &&
1271 IS_LITERAL (cexpr->right->ftype))
1272 return valCastLiteral (cexpr->ftype,
1273 floatFromVal (cexpr->right->opval.val));
1275 if (IS_AST_VALUE (cexpr))
1276 return cexpr->opval.val;
1279 werror (E_CONST_EXPECTED, "found expression");
1284 /* return the value */
1285 return cexpr->opval.val;
1289 /*-----------------------------------------------------------------*/
1290 /* isLabelInAst - will return true if a given label is found */
1291 /*-----------------------------------------------------------------*/
1293 isLabelInAst (symbol * label, ast * tree)
1295 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1298 if (IS_AST_OP (tree) &&
1299 tree->opval.op == LABEL &&
1300 isSymbolEqual (AST_SYMBOL (tree->left), label))
1303 return isLabelInAst (label, tree->right) &&
1304 isLabelInAst (label, tree->left);
1308 /*-----------------------------------------------------------------*/
1309 /* isLoopCountable - return true if the loop count can be determi- */
1310 /* -ned at compile time . */
1311 /*-----------------------------------------------------------------*/
1313 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1314 symbol ** sym, ast ** init, ast ** end)
1317 /* the loop is considered countable if the following
1318 conditions are true :-
1320 a) initExpr :- <sym> = <const>
1321 b) condExpr :- <sym> < <const1>
1322 c) loopExpr :- <sym> ++
1325 /* first check the initExpr */
1326 if (IS_AST_OP (initExpr) &&
1327 initExpr->opval.op == '=' && /* is assignment */
1328 IS_AST_SYM_VALUE (initExpr->left))
1329 { /* left is a symbol */
1331 *sym = AST_SYMBOL (initExpr->left);
1332 *init = initExpr->right;
1337 /* for now the symbol has to be of
1339 if (!IS_INTEGRAL ((*sym)->type))
1342 /* now check condExpr */
1343 if (IS_AST_OP (condExpr))
1346 switch (condExpr->opval.op)
1349 if (IS_AST_SYM_VALUE (condExpr->left) &&
1350 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1351 IS_AST_LIT_VALUE (condExpr->right))
1353 *end = condExpr->right;
1359 if (IS_AST_OP (condExpr->left) &&
1360 condExpr->left->opval.op == '>' &&
1361 IS_AST_LIT_VALUE (condExpr->left->right) &&
1362 IS_AST_SYM_VALUE (condExpr->left->left) &&
1363 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1366 *end = newNode ('+', condExpr->left->right,
1367 newAst_VALUE (constVal ("1")));
1378 /* check loop expression is of the form <sym>++ */
1379 if (!IS_AST_OP (loopExpr))
1382 /* check if <sym> ++ */
1383 if (loopExpr->opval.op == INC_OP)
1389 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1390 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1397 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1398 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1406 if (loopExpr->opval.op == ADD_ASSIGN)
1409 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1410 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1411 IS_AST_LIT_VALUE (loopExpr->right) &&
1412 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1420 /*-----------------------------------------------------------------*/
1421 /* astHasVolatile - returns true if ast contains any volatile */
1422 /*-----------------------------------------------------------------*/
1424 astHasVolatile (ast * tree)
1429 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1432 if (IS_AST_OP (tree))
1433 return astHasVolatile (tree->left) ||
1434 astHasVolatile (tree->right);
1439 /*-----------------------------------------------------------------*/
1440 /* astHasPointer - return true if the ast contains any ptr variable */
1441 /*-----------------------------------------------------------------*/
1443 astHasPointer (ast * tree)
1448 if (IS_AST_LINK (tree))
1451 /* if we hit an array expression then check
1452 only the left side */
1453 if (IS_AST_OP (tree) && tree->opval.op == '[')
1454 return astHasPointer (tree->left);
1456 if (IS_AST_VALUE (tree))
1457 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1459 return astHasPointer (tree->left) ||
1460 astHasPointer (tree->right);
1464 /*-----------------------------------------------------------------*/
1465 /* astHasSymbol - return true if the ast has the given symbol */
1466 /*-----------------------------------------------------------------*/
1468 astHasSymbol (ast * tree, symbol * sym)
1470 if (!tree || IS_AST_LINK (tree))
1473 if (IS_AST_VALUE (tree))
1475 if (IS_AST_SYM_VALUE (tree))
1476 return isSymbolEqual (AST_SYMBOL (tree), sym);
1481 return astHasSymbol (tree->left, sym) ||
1482 astHasSymbol (tree->right, sym);
1485 /*-----------------------------------------------------------------*/
1486 /* astHasDeref - return true if the ast has an indirect access */
1487 /*-----------------------------------------------------------------*/
1489 astHasDeref (ast * tree)
1491 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1494 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1496 return astHasDeref (tree->left) || astHasDeref (tree->right);
1499 /*-----------------------------------------------------------------*/
1500 /* isConformingBody - the loop body has to conform to a set of rules */
1501 /* for the loop to be considered reversible read on for rules */
1502 /*-----------------------------------------------------------------*/
1504 isConformingBody (ast * pbody, symbol * sym, ast * body)
1507 /* we are going to do a pre-order traversal of the
1508 tree && check for the following conditions. (essentially
1509 a set of very shallow tests )
1510 a) the sym passed does not participate in
1511 any arithmetic operation
1512 b) There are no function calls
1513 c) all jumps are within the body
1514 d) address of loop control variable not taken
1515 e) if an assignment has a pointer on the
1516 left hand side make sure right does not have
1517 loop control variable */
1519 /* if we reach the end or a leaf then true */
1520 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1523 /* if anything else is "volatile" */
1524 if (IS_VOLATILE (TETYPE (pbody)))
1527 /* we will walk the body in a pre-order traversal for
1529 switch (pbody->opval.op)
1531 /*------------------------------------------------------------------*/
1533 // if the loopvar is used as an index
1534 if (astHasSymbol(pbody->right, sym)) {
1537 return isConformingBody (pbody->right, sym, body);
1539 /*------------------------------------------------------------------*/
1544 /*------------------------------------------------------------------*/
1545 case INC_OP: /* incerement operator unary so left only */
1548 /* sure we are not sym is not modified */
1550 IS_AST_SYM_VALUE (pbody->left) &&
1551 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1555 IS_AST_SYM_VALUE (pbody->right) &&
1556 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1561 /*------------------------------------------------------------------*/
1563 case '*': /* can be unary : if right is null then unary operation */
1568 /* if right is NULL then unary operation */
1569 /*------------------------------------------------------------------*/
1570 /*----------------------------*/
1572 /*----------------------------*/
1575 if (IS_AST_SYM_VALUE (pbody->left) &&
1576 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1579 return isConformingBody (pbody->left, sym, body);
1583 if (astHasSymbol (pbody->left, sym) ||
1584 astHasSymbol (pbody->right, sym))
1589 /*------------------------------------------------------------------*/
1597 if (IS_AST_SYM_VALUE (pbody->left) &&
1598 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1601 if (IS_AST_SYM_VALUE (pbody->right) &&
1602 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1605 return isConformingBody (pbody->left, sym, body) &&
1606 isConformingBody (pbody->right, sym, body);
1613 if (IS_AST_SYM_VALUE (pbody->left) &&
1614 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1616 return isConformingBody (pbody->left, sym, body);
1618 /*------------------------------------------------------------------*/
1630 case SIZEOF: /* evaluate wihout code generation */
1632 return isConformingBody (pbody->left, sym, body) &&
1633 isConformingBody (pbody->right, sym, body);
1635 /*------------------------------------------------------------------*/
1638 /* if left has a pointer & right has loop
1639 control variable then we cannot */
1640 if (astHasPointer (pbody->left) &&
1641 astHasSymbol (pbody->right, sym))
1643 if (astHasVolatile (pbody->left))
1646 if (IS_AST_SYM_VALUE (pbody->left)) {
1647 // if the loopvar has an assignment
1648 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1650 // if the loopvar is used in another (maybe conditional) block
1651 if (astHasSymbol (pbody->right, sym) &&
1652 (pbody->level > body->level)) {
1657 if (astHasVolatile (pbody->left))
1660 if (astHasDeref(pbody->right)) return FALSE;
1662 return isConformingBody (pbody->left, sym, body) &&
1663 isConformingBody (pbody->right, sym, body);
1674 assert ("Parser should not have generated this\n");
1676 /*------------------------------------------------------------------*/
1677 /*----------------------------*/
1678 /* comma operator */
1679 /*----------------------------*/
1681 return isConformingBody (pbody->left, sym, body) &&
1682 isConformingBody (pbody->right, sym, body);
1684 /*------------------------------------------------------------------*/
1685 /*----------------------------*/
1687 /*----------------------------*/
1689 /* if local & not passed as paramater then ok */
1690 if (sym->level && !astHasSymbol(pbody->right,sym))
1694 /*------------------------------------------------------------------*/
1695 /*----------------------------*/
1696 /* return statement */
1697 /*----------------------------*/
1702 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1707 if (astHasSymbol (pbody->left, sym))
1714 return isConformingBody (pbody->left, sym, body) &&
1715 isConformingBody (pbody->right, sym, body);
1721 /*-----------------------------------------------------------------*/
1722 /* isLoopReversible - takes a for loop as input && returns true */
1723 /* if the for loop is reversible. If yes will set the value of */
1724 /* the loop control var & init value & termination value */
1725 /*-----------------------------------------------------------------*/
1727 isLoopReversible (ast * loop, symbol ** loopCntrl,
1728 ast ** init, ast ** end)
1730 /* if option says don't do it then don't */
1731 if (optimize.noLoopReverse)
1733 /* there are several tests to determine this */
1735 /* for loop has to be of the form
1736 for ( <sym> = <const1> ;
1737 [<sym> < <const2>] ;
1738 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1740 if (!isLoopCountable (AST_FOR (loop, initExpr),
1741 AST_FOR (loop, condExpr),
1742 AST_FOR (loop, loopExpr),
1743 loopCntrl, init, end))
1746 /* now do some serious checking on the body of the loop
1749 return isConformingBody (loop->left, *loopCntrl, loop->left);
1753 /*-----------------------------------------------------------------*/
1754 /* replLoopSym - replace the loop sym by loop sym -1 */
1755 /*-----------------------------------------------------------------*/
1757 replLoopSym (ast * body, symbol * sym)
1760 if (!body || IS_AST_LINK (body))
1763 if (IS_AST_SYM_VALUE (body))
1766 if (isSymbolEqual (AST_SYMBOL (body), sym))
1770 body->opval.op = '-';
1771 body->left = newAst_VALUE (symbolVal (sym));
1772 body->right = newAst_VALUE (constVal ("1"));
1780 replLoopSym (body->left, sym);
1781 replLoopSym (body->right, sym);
1785 /*-----------------------------------------------------------------*/
1786 /* reverseLoop - do the actual loop reversal */
1787 /*-----------------------------------------------------------------*/
1789 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1793 /* create the following tree
1798 if (sym) goto for_continue ;
1801 /* put it together piece by piece */
1802 rloop = newNode (NULLOP,
1803 createIf (newAst_VALUE (symbolVal (sym)),
1805 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1808 newAst_VALUE (symbolVal (sym)),
1811 replLoopSym (loop->left, sym);
1812 setAstLineno (rloop, init->lineno);
1814 rloop = newNode (NULLOP,
1816 newAst_VALUE (symbolVal (sym)),
1817 newNode ('-', end, init)),
1818 createLabel (AST_FOR (loop, continueLabel),
1822 newNode (SUB_ASSIGN,
1823 newAst_VALUE (symbolVal (sym)),
1824 newAst_VALUE (constVal ("1"))),
1827 rloop->lineno=init->lineno;
1828 return decorateType (rloop);
1832 /*-----------------------------------------------------------------*/
1833 /* decorateType - compute type for this tree also does type cheking */
1834 /* this is done bottom up, since type have to flow upwards */
1835 /* it also does constant folding, and paramater checking */
1836 /*-----------------------------------------------------------------*/
1838 decorateType (ast * tree)
1846 /* if already has type then do nothing */
1847 if (tree->decorated)
1850 tree->decorated = 1;
1852 /* print the line */
1853 /* if not block & function */
1854 if (tree->type == EX_OP &&
1855 (tree->opval.op != FUNCTION &&
1856 tree->opval.op != BLOCK &&
1857 tree->opval.op != NULLOP))
1859 filename = tree->filename;
1860 lineno = tree->lineno;
1863 /* if any child is an error | this one is an error do nothing */
1864 if (tree->isError ||
1865 (tree->left && tree->left->isError) ||
1866 (tree->right && tree->right->isError))
1869 /*------------------------------------------------------------------*/
1870 /*----------------------------*/
1871 /* leaf has been reached */
1872 /*----------------------------*/
1873 /* if this is of type value */
1874 /* just get the type */
1875 if (tree->type == EX_VALUE)
1878 if (IS_LITERAL (tree->opval.val->etype))
1881 /* if this is a character array then declare it */
1882 if (IS_ARRAY (tree->opval.val->type))
1883 tree->opval.val = stringToSymbol (tree->opval.val);
1885 /* otherwise just copy the type information */
1886 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1890 if (tree->opval.val->sym)
1892 /* if the undefined flag is set then give error message */
1893 if (tree->opval.val->sym->undefined)
1895 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1897 TTYPE (tree) = TETYPE (tree) =
1898 tree->opval.val->type = tree->opval.val->sym->type =
1899 tree->opval.val->etype = tree->opval.val->sym->etype =
1900 copyLinkChain (INTTYPE);
1905 /* if impilicit i.e. struct/union member then no type */
1906 if (tree->opval.val->sym->implicit)
1907 TTYPE (tree) = TETYPE (tree) = NULL;
1912 /* else copy the type */
1913 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1915 /* and mark it as referenced */
1916 tree->opval.val->sym->isref = 1;
1924 /* if type link for the case of cast */
1925 if (tree->type == EX_LINK)
1927 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1934 dtl = decorateType (tree->left);
1935 /* delay right side for '?' operator since conditional macro expansions might
1937 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1939 /* this is to take care of situations
1940 when the tree gets rewritten */
1941 if (dtl != tree->left)
1943 if (dtr != tree->right)
1947 /* depending on type of operator do */
1949 switch (tree->opval.op)
1951 /*------------------------------------------------------------------*/
1952 /*----------------------------*/
1954 /*----------------------------*/
1957 /* determine which is the array & which the index */
1958 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1961 ast *tempTree = tree->left;
1962 tree->left = tree->right;
1963 tree->right = tempTree;
1966 /* first check if this is a array or a pointer */
1967 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1969 werror (E_NEED_ARRAY_PTR, "[]");
1970 goto errorTreeReturn;
1973 /* check if the type of the idx */
1974 if (!IS_INTEGRAL (RTYPE (tree)))
1976 werror (E_IDX_NOT_INT);
1977 goto errorTreeReturn;
1980 /* if the left is an rvalue then error */
1983 werror (E_LVALUE_REQUIRED, "array access");
1984 goto errorTreeReturn;
1987 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1988 if (IS_PTR(LTYPE(tree))) {
1989 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1993 /*------------------------------------------------------------------*/
1994 /*----------------------------*/
1996 /*----------------------------*/
1998 /* if this is not a structure */
1999 if (!IS_STRUCT (LTYPE (tree)))
2001 werror (E_STRUCT_UNION, ".");
2002 goto errorTreeReturn;
2004 TTYPE (tree) = structElemType (LTYPE (tree),
2005 (tree->right->type == EX_VALUE ?
2006 tree->right->opval.val : NULL));
2007 TETYPE (tree) = getSpec (TTYPE (tree));
2010 /*------------------------------------------------------------------*/
2011 /*----------------------------*/
2012 /* struct/union pointer */
2013 /*----------------------------*/
2015 /* if not pointer to a structure */
2016 if (!IS_PTR (LTYPE (tree)))
2018 werror (E_PTR_REQD);
2019 goto errorTreeReturn;
2022 if (!IS_STRUCT (LTYPE (tree)->next))
2024 werror (E_STRUCT_UNION, "->");
2025 goto errorTreeReturn;
2028 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2029 (tree->right->type == EX_VALUE ?
2030 tree->right->opval.val : NULL));
2031 TETYPE (tree) = getSpec (TTYPE (tree));
2033 /* adjust the storage class */
2034 switch (DCL_TYPE(tree->left->ftype)) {
2038 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2041 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2046 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2049 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2052 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2061 /*------------------------------------------------------------------*/
2062 /*----------------------------*/
2063 /* ++/-- operation */
2064 /*----------------------------*/
2065 case INC_OP: /* incerement operator unary so left only */
2068 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2069 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2070 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2071 werror (E_CODE_WRITE, "++/--");
2080 /*------------------------------------------------------------------*/
2081 /*----------------------------*/
2083 /*----------------------------*/
2084 case '&': /* can be unary */
2085 /* if right is NULL then unary operation */
2086 if (tree->right) /* not an unary operation */
2089 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2091 werror (E_BITWISE_OP);
2092 werror (W_CONTINUE, "left & right types are ");
2093 printTypeChain (LTYPE (tree), stderr);
2094 fprintf (stderr, ",");
2095 printTypeChain (RTYPE (tree), stderr);
2096 fprintf (stderr, "\n");
2097 goto errorTreeReturn;
2100 /* if they are both literal */
2101 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2103 tree->type = EX_VALUE;
2104 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2105 valFromType (RETYPE (tree)), '&');
2107 tree->right = tree->left = NULL;
2108 TETYPE (tree) = tree->opval.val->etype;
2109 TTYPE (tree) = tree->opval.val->type;
2113 /* see if this is a GETHBIT operation if yes
2116 ast *otree = optimizeGetHbit (tree);
2119 return decorateType (otree);
2123 computeType (LTYPE (tree), RTYPE (tree));
2124 TETYPE (tree) = getSpec (TTYPE (tree));
2126 LRVAL (tree) = RRVAL (tree) = 1;
2130 /*------------------------------------------------------------------*/
2131 /*----------------------------*/
2133 /*----------------------------*/
2135 p->class = DECLARATOR;
2136 /* if bit field then error */
2137 if (IS_BITVAR (tree->left->etype))
2139 werror (E_ILLEGAL_ADDR, "address of bit variable");
2140 goto errorTreeReturn;
2143 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2145 werror (E_ILLEGAL_ADDR, "address of register variable");
2146 goto errorTreeReturn;
2149 if (IS_FUNC (LTYPE (tree)))
2151 // this ought to be ignored
2152 return (tree->left);
2155 if (IS_LITERAL(LTYPE(tree)))
2157 werror (E_ILLEGAL_ADDR, "address of literal");
2158 goto errorTreeReturn;
2163 werror (E_LVALUE_REQUIRED, "address of");
2164 goto errorTreeReturn;
2166 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2168 DCL_TYPE (p) = CPOINTER;
2169 DCL_PTR_CONST (p) = port->mem.code_ro;
2171 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2172 DCL_TYPE (p) = FPOINTER;
2173 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2174 DCL_TYPE (p) = PPOINTER;
2175 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2176 DCL_TYPE (p) = IPOINTER;
2177 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2178 DCL_TYPE (p) = EEPPOINTER;
2179 else if (SPEC_OCLS(tree->left->etype))
2180 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2182 DCL_TYPE (p) = POINTER;
2184 if (IS_AST_SYM_VALUE (tree->left))
2186 AST_SYMBOL (tree->left)->addrtaken = 1;
2187 AST_SYMBOL (tree->left)->allocreq = 1;
2190 p->next = LTYPE (tree);
2192 TETYPE (tree) = getSpec (TTYPE (tree));
2193 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2194 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2199 /*------------------------------------------------------------------*/
2200 /*----------------------------*/
2202 /*----------------------------*/
2204 /* if the rewrite succeeds then don't go any furthur */
2206 ast *wtree = optimizeRRCRLC (tree);
2208 return decorateType (wtree);
2210 /*------------------------------------------------------------------*/
2211 /*----------------------------*/
2213 /*----------------------------*/
2215 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2217 werror (E_BITWISE_OP);
2218 werror (W_CONTINUE, "left & right types are ");
2219 printTypeChain (LTYPE (tree), stderr);
2220 fprintf (stderr, ",");
2221 printTypeChain (RTYPE (tree), stderr);
2222 fprintf (stderr, "\n");
2223 goto errorTreeReturn;
2226 /* if they are both literal then */
2227 /* rewrite the tree */
2228 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2230 tree->type = EX_VALUE;
2231 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2232 valFromType (RETYPE (tree)),
2234 tree->right = tree->left = NULL;
2235 TETYPE (tree) = tree->opval.val->etype;
2236 TTYPE (tree) = tree->opval.val->type;
2239 LRVAL (tree) = RRVAL (tree) = 1;
2240 TETYPE (tree) = getSpec (TTYPE (tree) =
2241 computeType (LTYPE (tree),
2244 /*------------------------------------------------------------------*/
2245 /*----------------------------*/
2247 /*----------------------------*/
2249 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2251 werror (E_INVALID_OP, "divide");
2252 goto errorTreeReturn;
2254 /* if they are both literal then */
2255 /* rewrite the tree */
2256 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2258 tree->type = EX_VALUE;
2259 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2260 valFromType (RETYPE (tree)));
2261 tree->right = tree->left = NULL;
2262 TETYPE (tree) = getSpec (TTYPE (tree) =
2263 tree->opval.val->type);
2266 LRVAL (tree) = RRVAL (tree) = 1;
2267 TETYPE (tree) = getSpec (TTYPE (tree) =
2268 computeType (LTYPE (tree),
2272 /*------------------------------------------------------------------*/
2273 /*----------------------------*/
2275 /*----------------------------*/
2277 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2279 werror (E_BITWISE_OP);
2280 werror (W_CONTINUE, "left & right types are ");
2281 printTypeChain (LTYPE (tree), stderr);
2282 fprintf (stderr, ",");
2283 printTypeChain (RTYPE (tree), stderr);
2284 fprintf (stderr, "\n");
2285 goto errorTreeReturn;
2287 /* if they are both literal then */
2288 /* rewrite the tree */
2289 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2291 tree->type = EX_VALUE;
2292 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2293 valFromType (RETYPE (tree)));
2294 tree->right = tree->left = NULL;
2295 TETYPE (tree) = getSpec (TTYPE (tree) =
2296 tree->opval.val->type);
2299 LRVAL (tree) = RRVAL (tree) = 1;
2300 TETYPE (tree) = getSpec (TTYPE (tree) =
2301 computeType (LTYPE (tree),
2305 /*------------------------------------------------------------------*/
2306 /*----------------------------*/
2307 /* address dereference */
2308 /*----------------------------*/
2309 case '*': /* can be unary : if right is null then unary operation */
2312 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2314 werror (E_PTR_REQD);
2315 goto errorTreeReturn;
2320 werror (E_LVALUE_REQUIRED, "pointer deref");
2321 goto errorTreeReturn;
2323 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2324 LTYPE (tree)->next : NULL);
2325 TETYPE (tree) = getSpec (TTYPE (tree));
2326 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2330 /*------------------------------------------------------------------*/
2331 /*----------------------------*/
2332 /* multiplication */
2333 /*----------------------------*/
2334 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2336 werror (E_INVALID_OP, "multiplication");
2337 goto errorTreeReturn;
2340 /* if they are both literal then */
2341 /* rewrite the tree */
2342 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2344 tree->type = EX_VALUE;
2345 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2346 valFromType (RETYPE (tree)));
2347 tree->right = tree->left = NULL;
2348 TETYPE (tree) = getSpec (TTYPE (tree) =
2349 tree->opval.val->type);
2353 /* if left is a literal exchange left & right */
2354 if (IS_LITERAL (LTYPE (tree)))
2356 ast *tTree = tree->left;
2357 tree->left = tree->right;
2358 tree->right = tTree;
2361 LRVAL (tree) = RRVAL (tree) = 1;
2362 /* promote result to int if left & right are char
2363 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2364 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2365 TETYPE (tree) = getSpec (TTYPE (tree) =
2366 computeType (LTYPE (tree),
2368 SPEC_NOUN(TETYPE(tree)) = V_INT;
2370 TETYPE (tree) = getSpec (TTYPE (tree) =
2371 computeType (LTYPE (tree),
2376 /*------------------------------------------------------------------*/
2377 /*----------------------------*/
2378 /* unary '+' operator */
2379 /*----------------------------*/
2384 if (!IS_INTEGRAL (LTYPE (tree)))
2386 werror (E_UNARY_OP, '+');
2387 goto errorTreeReturn;
2390 /* if left is a literal then do it */
2391 if (IS_LITERAL (LTYPE (tree)))
2393 tree->type = EX_VALUE;
2394 tree->opval.val = valFromType (LETYPE (tree));
2396 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2400 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2404 /*------------------------------------------------------------------*/
2405 /*----------------------------*/
2407 /*----------------------------*/
2409 /* this is not a unary operation */
2410 /* if both pointers then problem */
2411 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2412 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2414 werror (E_PTR_PLUS_PTR);
2415 goto errorTreeReturn;
2418 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2419 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2421 werror (E_PLUS_INVALID, "+");
2422 goto errorTreeReturn;
2425 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2426 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2428 werror (E_PLUS_INVALID, "+");
2429 goto errorTreeReturn;
2431 /* if they are both literal then */
2432 /* rewrite the tree */
2433 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2435 tree->type = EX_VALUE;
2436 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2437 valFromType (RETYPE (tree)));
2438 tree->right = tree->left = NULL;
2439 TETYPE (tree) = getSpec (TTYPE (tree) =
2440 tree->opval.val->type);
2444 /* if the right is a pointer or left is a literal
2445 xchange left & right */
2446 if (IS_ARRAY (RTYPE (tree)) ||
2447 IS_PTR (RTYPE (tree)) ||
2448 IS_LITERAL (LTYPE (tree)))
2450 ast *tTree = tree->left;
2451 tree->left = tree->right;
2452 tree->right = tTree;
2455 LRVAL (tree) = RRVAL (tree) = 1;
2456 /* if the left is a pointer */
2457 if (IS_PTR (LTYPE (tree)))
2458 TETYPE (tree) = getSpec (TTYPE (tree) =
2461 TETYPE (tree) = getSpec (TTYPE (tree) =
2462 computeType (LTYPE (tree),
2466 /*------------------------------------------------------------------*/
2467 /*----------------------------*/
2469 /*----------------------------*/
2470 case '-': /* can be unary */
2471 /* if right is null then unary */
2475 if (!IS_ARITHMETIC (LTYPE (tree)))
2477 werror (E_UNARY_OP, tree->opval.op);
2478 goto errorTreeReturn;
2481 /* if left is a literal then do it */
2482 if (IS_LITERAL (LTYPE (tree)))
2484 tree->type = EX_VALUE;
2485 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2487 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2488 SPEC_USIGN(TETYPE(tree)) = 0;
2492 TTYPE (tree) = LTYPE (tree);
2496 /*------------------------------------------------------------------*/
2497 /*----------------------------*/
2499 /*----------------------------*/
2501 if (!(IS_PTR (LTYPE (tree)) ||
2502 IS_ARRAY (LTYPE (tree)) ||
2503 IS_ARITHMETIC (LTYPE (tree))))
2505 werror (E_PLUS_INVALID, "-");
2506 goto errorTreeReturn;
2509 if (!(IS_PTR (RTYPE (tree)) ||
2510 IS_ARRAY (RTYPE (tree)) ||
2511 IS_ARITHMETIC (RTYPE (tree))))
2513 werror (E_PLUS_INVALID, "-");
2514 goto errorTreeReturn;
2517 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2518 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2519 IS_INTEGRAL (RTYPE (tree))))
2521 werror (E_PLUS_INVALID, "-");
2522 goto errorTreeReturn;
2525 /* if they are both literal then */
2526 /* rewrite the tree */
2527 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2529 tree->type = EX_VALUE;
2530 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2531 valFromType (RETYPE (tree)));
2532 tree->right = tree->left = NULL;
2533 TETYPE (tree) = getSpec (TTYPE (tree) =
2534 tree->opval.val->type);
2538 /* if the left & right are equal then zero */
2539 if (isAstEqual (tree->left, tree->right))
2541 tree->type = EX_VALUE;
2542 tree->left = tree->right = NULL;
2543 tree->opval.val = constVal ("0");
2544 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2548 /* if both of them are pointers or arrays then */
2549 /* the result is going to be an integer */
2550 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2551 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2552 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2554 /* if only the left is a pointer */
2555 /* then result is a pointer */
2556 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2557 TETYPE (tree) = getSpec (TTYPE (tree) =
2560 TETYPE (tree) = getSpec (TTYPE (tree) =
2561 computeType (LTYPE (tree),
2563 LRVAL (tree) = RRVAL (tree) = 1;
2566 /*------------------------------------------------------------------*/
2567 /*----------------------------*/
2569 /*----------------------------*/
2571 /* can be only integral type */
2572 if (!IS_INTEGRAL (LTYPE (tree)))
2574 werror (E_UNARY_OP, tree->opval.op);
2575 goto errorTreeReturn;
2578 /* if left is a literal then do it */
2579 if (IS_LITERAL (LTYPE (tree)))
2581 tree->type = EX_VALUE;
2582 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2584 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2588 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2591 /*------------------------------------------------------------------*/
2592 /*----------------------------*/
2594 /*----------------------------*/
2596 /* can be pointer */
2597 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2598 !IS_PTR (LTYPE (tree)) &&
2599 !IS_ARRAY (LTYPE (tree)))
2601 werror (E_UNARY_OP, tree->opval.op);
2602 goto errorTreeReturn;
2605 /* if left is a literal then do it */
2606 if (IS_LITERAL (LTYPE (tree)))
2608 tree->type = EX_VALUE;
2609 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2611 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2615 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2618 /*------------------------------------------------------------------*/
2619 /*----------------------------*/
2621 /*----------------------------*/
2624 TTYPE (tree) = LTYPE (tree);
2625 TETYPE (tree) = LETYPE (tree);
2629 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2634 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2636 werror (E_SHIFT_OP_INVALID);
2637 werror (W_CONTINUE, "left & right types are ");
2638 printTypeChain (LTYPE (tree), stderr);
2639 fprintf (stderr, ",");
2640 printTypeChain (RTYPE (tree), stderr);
2641 fprintf (stderr, "\n");
2642 goto errorTreeReturn;
2645 /* if they are both literal then */
2646 /* rewrite the tree */
2647 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2649 tree->type = EX_VALUE;
2650 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2651 valFromType (RETYPE (tree)),
2652 (tree->opval.op == LEFT_OP ? 1 : 0));
2653 tree->right = tree->left = NULL;
2654 TETYPE (tree) = getSpec (TTYPE (tree) =
2655 tree->opval.val->type);
2658 /* a left shift must be done with at least 16bits */
2659 if ((tree->opval.op==LEFT_OP) && (getSize(LTYPE(tree))<2)) {
2662 decorateType (newNode (CAST,
2663 newAst_LINK(copyLinkChain(LTYPE(tree))),
2665 SPEC_NOUN(tree->left->left->ftype)=V_INT;
2667 /* if only the right side is a literal & we are
2668 shifting more than size of the left operand then zero */
2669 if (IS_LITERAL (RTYPE (tree)) &&
2670 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2671 (getSize (LTYPE (tree)) * 8))
2673 werror (W_SHIFT_CHANGED,
2674 (tree->opval.op == LEFT_OP ? "left" : "right"));
2675 tree->type = EX_VALUE;
2676 tree->left = tree->right = NULL;
2677 tree->opval.val = constVal ("0");
2678 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2681 LRVAL (tree) = RRVAL (tree) = 1;
2682 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2684 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2688 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2692 /*------------------------------------------------------------------*/
2693 /*----------------------------*/
2695 /*----------------------------*/
2696 case CAST: /* change the type */
2697 /* cannot cast to an aggregate type */
2698 if (IS_AGGREGATE (LTYPE (tree)))
2700 werror (E_CAST_ILLEGAL);
2701 goto errorTreeReturn;
2704 /* make sure the type is complete and sane */
2705 checkTypeSanity(LETYPE(tree), "(cast)");
2708 /* if the right is a literal replace the tree */
2709 if (IS_LITERAL (RETYPE (tree))) {
2710 if (!IS_PTR (LTYPE (tree))) {
2711 tree->type = EX_VALUE;
2713 valCastLiteral (LTYPE (tree),
2714 floatFromVal (valFromType (RETYPE (tree))));
2717 TTYPE (tree) = tree->opval.val->type;
2718 tree->values.literalFromCast = 1;
2719 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2720 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2721 sym_link *rest = LTYPE(tree)->next;
2722 werror(W_LITERAL_GENERIC);
2723 TTYPE(tree) = newLink();
2724 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2725 TTYPE(tree)->next = rest;
2726 tree->left->opval.lnk = TTYPE(tree);
2729 TTYPE (tree) = LTYPE (tree);
2733 TTYPE (tree) = LTYPE (tree);
2737 #if 0 // this is already checked, now this could be explicit
2738 /* if pointer to struct then check names */
2739 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2740 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2741 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2743 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2744 SPEC_STRUCT(LETYPE(tree))->tag);
2747 /* if the right is a literal replace the tree */
2748 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2749 tree->type = EX_VALUE;
2751 valCastLiteral (LTYPE (tree),
2752 floatFromVal (valFromType (RETYPE (tree))));
2755 TTYPE (tree) = tree->opval.val->type;
2756 tree->values.literalFromCast = 1;
2758 TTYPE (tree) = LTYPE (tree);
2762 TETYPE (tree) = getSpec (TTYPE (tree));
2766 /*------------------------------------------------------------------*/
2767 /*----------------------------*/
2768 /* logical &&, || */
2769 /*----------------------------*/
2772 /* each must me arithmetic type or be a pointer */
2773 if (!IS_PTR (LTYPE (tree)) &&
2774 !IS_ARRAY (LTYPE (tree)) &&
2775 !IS_INTEGRAL (LTYPE (tree)))
2777 werror (E_COMPARE_OP);
2778 goto errorTreeReturn;
2781 if (!IS_PTR (RTYPE (tree)) &&
2782 !IS_ARRAY (RTYPE (tree)) &&
2783 !IS_INTEGRAL (RTYPE (tree)))
2785 werror (E_COMPARE_OP);
2786 goto errorTreeReturn;
2788 /* if they are both literal then */
2789 /* rewrite the tree */
2790 if (IS_LITERAL (RTYPE (tree)) &&
2791 IS_LITERAL (LTYPE (tree)))
2793 tree->type = EX_VALUE;
2794 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2795 valFromType (RETYPE (tree)),
2797 tree->right = tree->left = NULL;
2798 TETYPE (tree) = getSpec (TTYPE (tree) =
2799 tree->opval.val->type);
2802 LRVAL (tree) = RRVAL (tree) = 1;
2803 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2806 /*------------------------------------------------------------------*/
2807 /*----------------------------*/
2808 /* comparison operators */
2809 /*----------------------------*/
2817 ast *lt = optimizeCompare (tree);
2823 /* if they are pointers they must be castable */
2824 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2826 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2828 werror (E_COMPARE_OP);
2829 fprintf (stderr, "comparing type ");
2830 printTypeChain (LTYPE (tree), stderr);
2831 fprintf (stderr, "to type ");
2832 printTypeChain (RTYPE (tree), stderr);
2833 fprintf (stderr, "\n");
2834 goto errorTreeReturn;
2837 /* else they should be promotable to one another */
2840 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2841 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2843 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2845 werror (E_COMPARE_OP);
2846 fprintf (stderr, "comparing type ");
2847 printTypeChain (LTYPE (tree), stderr);
2848 fprintf (stderr, "to type ");
2849 printTypeChain (RTYPE (tree), stderr);
2850 fprintf (stderr, "\n");
2851 goto errorTreeReturn;
2854 /* if unsigned value < 0 then always false */
2855 /* if (unsigned value) > 0 then (unsigned value) */
2856 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2857 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2859 if (tree->opval.op == '<') {
2862 if (tree->opval.op == '>') {
2866 /* if they are both literal then */
2867 /* rewrite the tree */
2868 if (IS_LITERAL (RTYPE (tree)) &&
2869 IS_LITERAL (LTYPE (tree)))
2871 tree->type = EX_VALUE;
2872 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2873 valFromType (RETYPE (tree)),
2875 tree->right = tree->left = NULL;
2876 TETYPE (tree) = getSpec (TTYPE (tree) =
2877 tree->opval.val->type);
2880 LRVAL (tree) = RRVAL (tree) = 1;
2881 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2884 /*------------------------------------------------------------------*/
2885 /*----------------------------*/
2887 /*----------------------------*/
2888 case SIZEOF: /* evaluate wihout code generation */
2889 /* change the type to a integer */
2890 tree->type = EX_VALUE;
2891 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2892 tree->opval.val = constVal (buffer);
2893 tree->right = tree->left = NULL;
2894 TETYPE (tree) = getSpec (TTYPE (tree) =
2895 tree->opval.val->type);
2898 /*------------------------------------------------------------------*/
2899 /*----------------------------*/
2901 /*----------------------------*/
2903 /* return typeof enum value */
2904 tree->type = EX_VALUE;
2907 if (IS_SPEC(tree->right->ftype)) {
2908 switch (SPEC_NOUN(tree->right->ftype)) {
2910 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2911 else typeofv = TYPEOF_INT;
2914 typeofv = TYPEOF_FLOAT;
2917 typeofv = TYPEOF_CHAR;
2920 typeofv = TYPEOF_VOID;
2923 typeofv = TYPEOF_STRUCT;
2926 typeofv = TYPEOF_BIT;
2929 typeofv = TYPEOF_SBIT;
2935 switch (DCL_TYPE(tree->right->ftype)) {
2937 typeofv = TYPEOF_POINTER;
2940 typeofv = TYPEOF_FPOINTER;
2943 typeofv = TYPEOF_CPOINTER;
2946 typeofv = TYPEOF_GPOINTER;
2949 typeofv = TYPEOF_PPOINTER;
2952 typeofv = TYPEOF_IPOINTER;
2955 typeofv = TYPEOF_ARRAY;
2958 typeofv = TYPEOF_FUNCTION;
2964 sprintf (buffer, "%d", typeofv);
2965 tree->opval.val = constVal (buffer);
2966 tree->right = tree->left = NULL;
2967 TETYPE (tree) = getSpec (TTYPE (tree) =
2968 tree->opval.val->type);
2971 /*------------------------------------------------------------------*/
2972 /*----------------------------*/
2973 /* conditional operator '?' */
2974 /*----------------------------*/
2976 /* the type is value of the colon operator (on the right) */
2977 assert(IS_COLON_OP(tree->right));
2978 /* if already known then replace the tree : optimizer will do it
2979 but faster to do it here */
2980 if (IS_LITERAL (LTYPE(tree))) {
2981 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2982 return decorateType(tree->right->left) ;
2984 return decorateType(tree->right->right) ;
2987 tree->right = decorateType(tree->right);
2988 TTYPE (tree) = RTYPE(tree);
2989 TETYPE (tree) = getSpec (TTYPE (tree));
2994 /* if they don't match we have a problem */
2995 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2997 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2998 goto errorTreeReturn;
3001 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3002 TETYPE (tree) = getSpec (TTYPE (tree));
3006 #if 0 // assignment operators are converted by the parser
3007 /*------------------------------------------------------------------*/
3008 /*----------------------------*/
3009 /* assignment operators */
3010 /*----------------------------*/
3013 /* for these it must be both must be integral */
3014 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3015 !IS_ARITHMETIC (RTYPE (tree)))
3017 werror (E_OPS_INTEGRAL);
3018 goto errorTreeReturn;
3021 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3023 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3024 werror (E_CODE_WRITE, " ");
3028 werror (E_LVALUE_REQUIRED, "*= or /=");
3029 goto errorTreeReturn;
3040 /* for these it must be both must be integral */
3041 if (!IS_INTEGRAL (LTYPE (tree)) ||
3042 !IS_INTEGRAL (RTYPE (tree)))
3044 werror (E_OPS_INTEGRAL);
3045 goto errorTreeReturn;
3048 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3050 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3051 werror (E_CODE_WRITE, " ");
3055 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3056 goto errorTreeReturn;
3062 /*------------------------------------------------------------------*/
3063 /*----------------------------*/
3065 /*----------------------------*/
3067 if (!(IS_PTR (LTYPE (tree)) ||
3068 IS_ARITHMETIC (LTYPE (tree))))
3070 werror (E_PLUS_INVALID, "-=");
3071 goto errorTreeReturn;
3074 if (!(IS_PTR (RTYPE (tree)) ||
3075 IS_ARITHMETIC (RTYPE (tree))))
3077 werror (E_PLUS_INVALID, "-=");
3078 goto errorTreeReturn;
3081 TETYPE (tree) = getSpec (TTYPE (tree) =
3082 computeType (LTYPE (tree),
3085 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3086 werror (E_CODE_WRITE, " ");
3090 werror (E_LVALUE_REQUIRED, "-=");
3091 goto errorTreeReturn;
3097 /*------------------------------------------------------------------*/
3098 /*----------------------------*/
3100 /*----------------------------*/
3102 /* this is not a unary operation */
3103 /* if both pointers then problem */
3104 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3106 werror (E_PTR_PLUS_PTR);
3107 goto errorTreeReturn;
3110 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3112 werror (E_PLUS_INVALID, "+=");
3113 goto errorTreeReturn;
3116 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3118 werror (E_PLUS_INVALID, "+=");
3119 goto errorTreeReturn;
3122 TETYPE (tree) = getSpec (TTYPE (tree) =
3123 computeType (LTYPE (tree),
3126 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3127 werror (E_CODE_WRITE, " ");
3131 werror (E_LVALUE_REQUIRED, "+=");
3132 goto errorTreeReturn;
3135 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3136 tree->opval.op = '=';
3141 /*------------------------------------------------------------------*/
3142 /*----------------------------*/
3143 /* straight assignemnt */
3144 /*----------------------------*/
3146 /* cannot be an aggregate */
3147 if (IS_AGGREGATE (LTYPE (tree)))
3149 werror (E_AGGR_ASSIGN);
3150 goto errorTreeReturn;
3153 /* they should either match or be castable */
3154 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3156 werror (E_TYPE_MISMATCH, "assignment", " ");
3157 printFromToType(RTYPE(tree),LTYPE(tree));
3158 //goto errorTreeReturn;
3161 /* if the left side of the tree is of type void
3162 then report error */
3163 if (IS_VOID (LTYPE (tree)))
3165 werror (E_CAST_ZERO);
3166 printFromToType(RTYPE(tree), LTYPE(tree));
3169 TETYPE (tree) = getSpec (TTYPE (tree) =
3173 if (!tree->initMode ) {
3174 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3175 werror (E_CODE_WRITE, " ");
3179 werror (E_LVALUE_REQUIRED, "=");
3180 goto errorTreeReturn;
3185 /*------------------------------------------------------------------*/
3186 /*----------------------------*/
3187 /* comma operator */
3188 /*----------------------------*/
3190 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3193 /*------------------------------------------------------------------*/
3194 /*----------------------------*/
3196 /*----------------------------*/
3200 if (processParms (tree->left,
3201 FUNC_ARGS(tree->left->ftype),
3202 tree->right, &parmNumber, TRUE)) {
3203 goto errorTreeReturn;
3206 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3207 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3209 //FUNC_ARGS(tree->left->ftype) =
3210 //reverseVal (FUNC_ARGS(tree->left->ftype));
3211 reverseParms (tree->right);
3214 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3217 /*------------------------------------------------------------------*/
3218 /*----------------------------*/
3219 /* return statement */
3220 /*----------------------------*/
3225 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3227 werror (W_RETURN_MISMATCH);
3228 printFromToType (RTYPE(tree), currFunc->type->next);
3229 goto errorTreeReturn;
3232 if (IS_VOID (currFunc->type->next)
3234 !IS_VOID (RTYPE (tree)))
3236 werror (E_FUNC_VOID);
3237 goto errorTreeReturn;
3240 /* if there is going to be a casing required then add it */
3241 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3244 decorateType (newNode (CAST,
3245 newAst_LINK (copyLinkChain (currFunc->type->next)),
3254 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3256 werror (E_VOID_FUNC, currFunc->name);
3257 goto errorTreeReturn;
3260 TTYPE (tree) = TETYPE (tree) = NULL;
3263 /*------------------------------------------------------------------*/
3264 /*----------------------------*/
3265 /* switch statement */
3266 /*----------------------------*/
3268 /* the switch value must be an integer */
3269 if (!IS_INTEGRAL (LTYPE (tree)))
3271 werror (E_SWITCH_NON_INTEGER);
3272 goto errorTreeReturn;
3275 TTYPE (tree) = TETYPE (tree) = NULL;
3278 /*------------------------------------------------------------------*/
3279 /*----------------------------*/
3281 /*----------------------------*/
3283 tree->left = backPatchLabels (tree->left,
3286 TTYPE (tree) = TETYPE (tree) = NULL;
3289 /*------------------------------------------------------------------*/
3290 /*----------------------------*/
3292 /*----------------------------*/
3295 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3296 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3297 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3299 /* if the for loop is reversible then
3300 reverse it otherwise do what we normally
3306 if (isLoopReversible (tree, &sym, &init, &end))
3307 return reverseLoop (tree, sym, init, end);
3309 return decorateType (createFor (AST_FOR (tree, trueLabel),
3310 AST_FOR (tree, continueLabel),
3311 AST_FOR (tree, falseLabel),
3312 AST_FOR (tree, condLabel),
3313 AST_FOR (tree, initExpr),
3314 AST_FOR (tree, condExpr),
3315 AST_FOR (tree, loopExpr),
3319 TTYPE (tree) = TETYPE (tree) = NULL;
3323 /* some error found this tree will be killed */
3325 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3326 tree->opval.op = NULLOP;
3332 /*-----------------------------------------------------------------*/
3333 /* sizeofOp - processes size of operation */
3334 /*-----------------------------------------------------------------*/
3336 sizeofOp (sym_link * type)
3340 /* make sure the type is complete and sane */
3341 checkTypeSanity(type, "(sizeof)");
3343 /* get the size and convert it to character */
3344 sprintf (buff, "%d", getSize (type));
3346 /* now convert into value */
3347 return constVal (buff);
3351 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3352 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3353 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3354 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3355 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3356 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3357 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3359 /*-----------------------------------------------------------------*/
3360 /* backPatchLabels - change and or not operators to flow control */
3361 /*-----------------------------------------------------------------*/
3363 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3369 if (!(IS_ANDORNOT (tree)))
3372 /* if this an and */
3375 static int localLbl = 0;
3378 sprintf (buffer, "_and_%d", localLbl++);
3379 localLabel = newSymbol (buffer, NestLevel);
3381 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3383 /* if left is already a IFX then just change the if true label in that */
3384 if (!IS_IFX (tree->left))
3385 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3387 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3388 /* right is a IFX then just join */
3389 if (IS_IFX (tree->right))
3390 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3392 tree->right = createLabel (localLabel, tree->right);
3393 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3395 return newNode (NULLOP, tree->left, tree->right);
3398 /* if this is an or operation */
3401 static int localLbl = 0;
3404 sprintf (buffer, "_or_%d", localLbl++);
3405 localLabel = newSymbol (buffer, NestLevel);
3407 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3409 /* if left is already a IFX then just change the if true label in that */
3410 if (!IS_IFX (tree->left))
3411 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3413 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3414 /* right is a IFX then just join */
3415 if (IS_IFX (tree->right))
3416 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3418 tree->right = createLabel (localLabel, tree->right);
3419 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3421 return newNode (NULLOP, tree->left, tree->right);
3427 int wasnot = IS_NOT (tree->left);
3428 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3430 /* if the left is already a IFX */
3431 if (!IS_IFX (tree->left))
3432 tree->left = newNode (IFX, tree->left, NULL);
3436 tree->left->trueLabel = trueLabel;
3437 tree->left->falseLabel = falseLabel;
3441 tree->left->trueLabel = falseLabel;
3442 tree->left->falseLabel = trueLabel;
3449 tree->trueLabel = trueLabel;
3450 tree->falseLabel = falseLabel;
3457 /*-----------------------------------------------------------------*/
3458 /* createBlock - create expression tree for block */
3459 /*-----------------------------------------------------------------*/
3461 createBlock (symbol * decl, ast * body)
3465 /* if the block has nothing */
3469 ex = newNode (BLOCK, NULL, body);
3470 ex->values.sym = decl;
3472 ex->right = ex->right;
3478 /*-----------------------------------------------------------------*/
3479 /* createLabel - creates the expression tree for labels */
3480 /*-----------------------------------------------------------------*/
3482 createLabel (symbol * label, ast * stmnt)
3485 char name[SDCC_NAME_MAX + 1];
3488 /* must create fresh symbol if the symbol name */
3489 /* exists in the symbol table, since there can */
3490 /* be a variable with the same name as the labl */
3491 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3492 (csym->level == label->level))
3493 label = newSymbol (label->name, label->level);
3495 /* change the name before putting it in add _ */
3496 sprintf (name, "%s", label->name);
3498 /* put the label in the LabelSymbol table */
3499 /* but first check if a label of the same */
3501 if ((csym = findSym (LabelTab, NULL, name)))
3502 werror (E_DUPLICATE_LABEL, label->name);
3504 addSym (LabelTab, label, name, label->level, 0, 0);
3507 label->key = labelKey++;
3508 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3514 /*-----------------------------------------------------------------*/
3515 /* createCase - generates the parsetree for a case statement */
3516 /*-----------------------------------------------------------------*/
3518 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3520 char caseLbl[SDCC_NAME_MAX + 1];
3524 /* if the switch statement does not exist */
3525 /* then case is out of context */
3528 werror (E_CASE_CONTEXT);
3532 caseVal = decorateType (resolveSymbols (caseVal));
3533 /* if not a constant then error */
3534 if (!IS_LITERAL (caseVal->ftype))
3536 werror (E_CASE_CONSTANT);
3540 /* if not a integer than error */
3541 if (!IS_INTEGRAL (caseVal->ftype))
3543 werror (E_CASE_NON_INTEGER);
3547 /* find the end of the switch values chain */
3548 if (!(val = swStat->values.switchVals.swVals))
3549 swStat->values.switchVals.swVals = caseVal->opval.val;
3552 /* also order the cases according to value */
3554 int cVal = (int) floatFromVal (caseVal->opval.val);
3555 while (val && (int) floatFromVal (val) < cVal)
3561 /* if we reached the end then */
3564 pval->next = caseVal->opval.val;
3568 /* we found a value greater than */
3569 /* the current value we must add this */
3570 /* before the value */
3571 caseVal->opval.val->next = val;
3573 /* if this was the first in chain */
3574 if (swStat->values.switchVals.swVals == val)
3575 swStat->values.switchVals.swVals =
3578 pval->next = caseVal->opval.val;
3583 /* create the case label */
3584 sprintf (caseLbl, "_case_%d_%d",
3585 swStat->values.switchVals.swNum,
3586 (int) floatFromVal (caseVal->opval.val));
3588 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3593 /*-----------------------------------------------------------------*/
3594 /* createDefault - creates the parse tree for the default statement */
3595 /*-----------------------------------------------------------------*/
3597 createDefault (ast * swStat, ast * stmnt)
3599 char defLbl[SDCC_NAME_MAX + 1];
3601 /* if the switch statement does not exist */
3602 /* then case is out of context */
3605 werror (E_CASE_CONTEXT);
3609 /* turn on the default flag */
3610 swStat->values.switchVals.swDefault = 1;
3612 /* create the label */
3613 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3614 return createLabel (newSymbol (defLbl, 0), stmnt);
3617 /*-----------------------------------------------------------------*/
3618 /* createIf - creates the parsetree for the if statement */
3619 /*-----------------------------------------------------------------*/
3621 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3623 static int Lblnum = 0;
3625 symbol *ifTrue, *ifFalse, *ifEnd;
3627 /* if neither exists */
3628 if (!elseBody && !ifBody) {
3629 // if there are no side effects (i++, j() etc)
3630 if (!hasSEFcalls(condAst)) {
3635 /* create the labels */
3636 sprintf (buffer, "_iffalse_%d", Lblnum);
3637 ifFalse = newSymbol (buffer, NestLevel);
3638 /* if no else body then end == false */
3643 sprintf (buffer, "_ifend_%d", Lblnum);
3644 ifEnd = newSymbol (buffer, NestLevel);
3647 sprintf (buffer, "_iftrue_%d", Lblnum);
3648 ifTrue = newSymbol (buffer, NestLevel);
3652 /* attach the ifTrue label to the top of it body */
3653 ifBody = createLabel (ifTrue, ifBody);
3654 /* attach a goto end to the ifBody if else is present */
3657 ifBody = newNode (NULLOP, ifBody,
3659 newAst_VALUE (symbolVal (ifEnd)),
3661 /* put the elseLabel on the else body */
3662 elseBody = createLabel (ifFalse, elseBody);
3663 /* out the end at the end of the body */
3664 elseBody = newNode (NULLOP,
3666 createLabel (ifEnd, NULL));
3670 ifBody = newNode (NULLOP, ifBody,
3671 createLabel (ifFalse, NULL));
3673 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3674 if (IS_IFX (condAst))
3677 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3679 return newNode (NULLOP, ifTree,
3680 newNode (NULLOP, ifBody, elseBody));
3684 /*-----------------------------------------------------------------*/
3685 /* createDo - creates parse tree for do */
3688 /* _docontinue_n: */
3689 /* condition_expression +-> trueLabel -> _dobody_n */
3691 /* +-> falseLabel-> _dobreak_n */
3693 /*-----------------------------------------------------------------*/
3695 createDo (symbol * trueLabel, symbol * continueLabel,
3696 symbol * falseLabel, ast * condAst, ast * doBody)
3701 /* if the body does not exist then it is simple */
3704 condAst = backPatchLabels (condAst, continueLabel, NULL);
3705 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3706 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3707 doTree->trueLabel = continueLabel;
3708 doTree->falseLabel = NULL;
3712 /* otherwise we have a body */
3713 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3715 /* attach the body label to the top */
3716 doBody = createLabel (trueLabel, doBody);
3717 /* attach the continue label to end of body */
3718 doBody = newNode (NULLOP, doBody,
3719 createLabel (continueLabel, NULL));
3721 /* now put the break label at the end */
3722 if (IS_IFX (condAst))
3725 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3727 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3729 /* putting it together */
3730 return newNode (NULLOP, doBody, doTree);
3733 /*-----------------------------------------------------------------*/
3734 /* createFor - creates parse tree for 'for' statement */
3737 /* condExpr +-> trueLabel -> _forbody_n */
3739 /* +-> falseLabel-> _forbreak_n */
3742 /* _forcontinue_n: */
3744 /* goto _forcond_n ; */
3746 /*-----------------------------------------------------------------*/
3748 createFor (symbol * trueLabel, symbol * continueLabel,
3749 symbol * falseLabel, symbol * condLabel,
3750 ast * initExpr, ast * condExpr, ast * loopExpr,
3755 /* if loopexpression not present then we can generate it */
3756 /* the same way as a while */
3758 return newNode (NULLOP, initExpr,
3759 createWhile (trueLabel, continueLabel,
3760 falseLabel, condExpr, forBody));
3761 /* vanilla for statement */
3762 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3764 if (condExpr && !IS_IFX (condExpr))
3765 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3768 /* attach condition label to condition */
3769 condExpr = createLabel (condLabel, condExpr);
3771 /* attach body label to body */
3772 forBody = createLabel (trueLabel, forBody);
3774 /* attach continue to forLoop expression & attach */
3775 /* goto the forcond @ and of loopExpression */
3776 loopExpr = createLabel (continueLabel,
3780 newAst_VALUE (symbolVal (condLabel)),
3782 /* now start putting them together */
3783 forTree = newNode (NULLOP, initExpr, condExpr);
3784 forTree = newNode (NULLOP, forTree, forBody);
3785 forTree = newNode (NULLOP, forTree, loopExpr);
3786 /* finally add the break label */
3787 forTree = newNode (NULLOP, forTree,
3788 createLabel (falseLabel, NULL));
3792 /*-----------------------------------------------------------------*/
3793 /* createWhile - creates parse tree for while statement */
3794 /* the while statement will be created as follows */
3796 /* _while_continue_n: */
3797 /* condition_expression +-> trueLabel -> _while_boby_n */
3799 /* +-> falseLabel -> _while_break_n */
3800 /* _while_body_n: */
3802 /* goto _while_continue_n */
3803 /* _while_break_n: */
3804 /*-----------------------------------------------------------------*/
3806 createWhile (symbol * trueLabel, symbol * continueLabel,
3807 symbol * falseLabel, ast * condExpr, ast * whileBody)
3811 /* put the continue label */
3812 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3813 condExpr = createLabel (continueLabel, condExpr);
3814 condExpr->lineno = 0;
3816 /* put the body label in front of the body */
3817 whileBody = createLabel (trueLabel, whileBody);
3818 whileBody->lineno = 0;
3819 /* put a jump to continue at the end of the body */
3820 /* and put break label at the end of the body */
3821 whileBody = newNode (NULLOP,
3824 newAst_VALUE (symbolVal (continueLabel)),
3825 createLabel (falseLabel, NULL)));
3827 /* put it all together */
3828 if (IS_IFX (condExpr))
3829 whileTree = condExpr;
3832 whileTree = newNode (IFX, condExpr, NULL);
3833 /* put the true & false labels in place */
3834 whileTree->trueLabel = trueLabel;
3835 whileTree->falseLabel = falseLabel;
3838 return newNode (NULLOP, whileTree, whileBody);
3841 /*-----------------------------------------------------------------*/
3842 /* optimizeGetHbit - get highest order bit of the expression */
3843 /*-----------------------------------------------------------------*/
3845 optimizeGetHbit (ast * tree)
3848 /* if this is not a bit and */
3849 if (!IS_BITAND (tree))
3852 /* will look for tree of the form
3853 ( expr >> ((sizeof expr) -1) ) & 1 */
3854 if (!IS_AST_LIT_VALUE (tree->right))
3857 if (AST_LIT_VALUE (tree->right) != 1)
3860 if (!IS_RIGHT_OP (tree->left))
3863 if (!IS_AST_LIT_VALUE (tree->left->right))
3866 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3867 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3870 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3874 /*-----------------------------------------------------------------*/
3875 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3876 /*-----------------------------------------------------------------*/
3878 optimizeRRCRLC (ast * root)
3880 /* will look for trees of the form
3881 (?expr << 1) | (?expr >> 7) or
3882 (?expr >> 7) | (?expr << 1) will make that
3883 into a RLC : operation ..
3885 (?expr >> 1) | (?expr << 7) or
3886 (?expr << 7) | (?expr >> 1) will make that
3887 into a RRC operation
3888 note : by 7 I mean (number of bits required to hold the
3890 /* if the root operations is not a | operation the not */
3891 if (!IS_BITOR (root))
3894 /* I have to think of a better way to match patterns this sucks */
3895 /* that aside let start looking for the first case : I use a the
3896 negative check a lot to improve the efficiency */
3897 /* (?expr << 1) | (?expr >> 7) */
3898 if (IS_LEFT_OP (root->left) &&
3899 IS_RIGHT_OP (root->right))
3902 if (!SPEC_USIGN (TETYPE (root->left->left)))
3905 if (!IS_AST_LIT_VALUE (root->left->right) ||
3906 !IS_AST_LIT_VALUE (root->right->right))
3909 /* make sure it is the same expression */
3910 if (!isAstEqual (root->left->left,
3914 if (AST_LIT_VALUE (root->left->right) != 1)
3917 if (AST_LIT_VALUE (root->right->right) !=
3918 (getSize (TTYPE (root->left->left)) * 8 - 1))
3921 /* whew got the first case : create the AST */
3922 return newNode (RLC, root->left->left, NULL);
3926 /* check for second case */
3927 /* (?expr >> 7) | (?expr << 1) */
3928 if (IS_LEFT_OP (root->right) &&
3929 IS_RIGHT_OP (root->left))
3932 if (!SPEC_USIGN (TETYPE (root->left->left)))
3935 if (!IS_AST_LIT_VALUE (root->left->right) ||
3936 !IS_AST_LIT_VALUE (root->right->right))
3939 /* make sure it is the same symbol */
3940 if (!isAstEqual (root->left->left,
3944 if (AST_LIT_VALUE (root->right->right) != 1)
3947 if (AST_LIT_VALUE (root->left->right) !=
3948 (getSize (TTYPE (root->left->left)) * 8 - 1))
3951 /* whew got the first case : create the AST */
3952 return newNode (RLC, root->left->left, NULL);
3957 /* third case for RRC */
3958 /* (?symbol >> 1) | (?symbol << 7) */
3959 if (IS_LEFT_OP (root->right) &&
3960 IS_RIGHT_OP (root->left))
3963 if (!SPEC_USIGN (TETYPE (root->left->left)))
3966 if (!IS_AST_LIT_VALUE (root->left->right) ||
3967 !IS_AST_LIT_VALUE (root->right->right))
3970 /* make sure it is the same symbol */
3971 if (!isAstEqual (root->left->left,
3975 if (AST_LIT_VALUE (root->left->right) != 1)
3978 if (AST_LIT_VALUE (root->right->right) !=
3979 (getSize (TTYPE (root->left->left)) * 8 - 1))
3982 /* whew got the first case : create the AST */
3983 return newNode (RRC, root->left->left, NULL);
3987 /* fourth and last case for now */
3988 /* (?symbol << 7) | (?symbol >> 1) */
3989 if (IS_RIGHT_OP (root->right) &&
3990 IS_LEFT_OP (root->left))
3993 if (!SPEC_USIGN (TETYPE (root->left->left)))
3996 if (!IS_AST_LIT_VALUE (root->left->right) ||
3997 !IS_AST_LIT_VALUE (root->right->right))
4000 /* make sure it is the same symbol */
4001 if (!isAstEqual (root->left->left,
4005 if (AST_LIT_VALUE (root->right->right) != 1)
4008 if (AST_LIT_VALUE (root->left->right) !=
4009 (getSize (TTYPE (root->left->left)) * 8 - 1))
4012 /* whew got the first case : create the AST */
4013 return newNode (RRC, root->left->left, NULL);
4017 /* not found return root */
4021 /*-----------------------------------------------------------------*/
4022 /* optimizeCompare - otimizes compares for bit variables */
4023 /*-----------------------------------------------------------------*/
4025 optimizeCompare (ast * root)
4027 ast *optExpr = NULL;
4030 unsigned int litValue;
4032 /* if nothing then return nothing */
4036 /* if not a compare op then do leaves */
4037 if (!IS_COMPARE_OP (root))
4039 root->left = optimizeCompare (root->left);
4040 root->right = optimizeCompare (root->right);
4044 /* if left & right are the same then depending
4045 of the operation do */
4046 if (isAstEqual (root->left, root->right))
4048 switch (root->opval.op)
4053 optExpr = newAst_VALUE (constVal ("0"));
4058 optExpr = newAst_VALUE (constVal ("1"));
4062 return decorateType (optExpr);
4065 vleft = (root->left->type == EX_VALUE ?
4066 root->left->opval.val : NULL);
4068 vright = (root->right->type == EX_VALUE ?
4069 root->right->opval.val : NULL);
4071 /* if left is a BITVAR in BITSPACE */
4072 /* and right is a LITERAL then opt- */
4073 /* imize else do nothing */
4074 if (vleft && vright &&
4075 IS_BITVAR (vleft->etype) &&
4076 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4077 IS_LITERAL (vright->etype))
4080 /* if right side > 1 then comparison may never succeed */
4081 if ((litValue = (int) floatFromVal (vright)) > 1)
4083 werror (W_BAD_COMPARE);
4089 switch (root->opval.op)
4091 case '>': /* bit value greater than 1 cannot be */
4092 werror (W_BAD_COMPARE);
4096 case '<': /* bit value < 1 means 0 */
4098 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4101 case LE_OP: /* bit value <= 1 means no check */
4102 optExpr = newAst_VALUE (vright);
4105 case GE_OP: /* bit value >= 1 means only check for = */
4107 optExpr = newAst_VALUE (vleft);
4112 { /* literal is zero */
4113 switch (root->opval.op)
4115 case '<': /* bit value < 0 cannot be */
4116 werror (W_BAD_COMPARE);
4120 case '>': /* bit value > 0 means 1 */
4122 optExpr = newAst_VALUE (vleft);
4125 case LE_OP: /* bit value <= 0 means no check */
4126 case GE_OP: /* bit value >= 0 means no check */
4127 werror (W_BAD_COMPARE);
4131 case EQ_OP: /* bit == 0 means ! of bit */
4132 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4136 return decorateType (resolveSymbols (optExpr));
4137 } /* end-of-if of BITVAR */
4142 /*-----------------------------------------------------------------*/
4143 /* addSymToBlock : adds the symbol to the first block we find */
4144 /*-----------------------------------------------------------------*/
4146 addSymToBlock (symbol * sym, ast * tree)
4148 /* reached end of tree or a leaf */
4149 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4153 if (IS_AST_OP (tree) &&
4154 tree->opval.op == BLOCK)
4157 symbol *lsym = copySymbol (sym);
4159 lsym->next = AST_VALUES (tree, sym);
4160 AST_VALUES (tree, sym) = lsym;
4164 addSymToBlock (sym, tree->left);
4165 addSymToBlock (sym, tree->right);
4168 /*-----------------------------------------------------------------*/
4169 /* processRegParms - do processing for register parameters */
4170 /*-----------------------------------------------------------------*/
4172 processRegParms (value * args, ast * body)
4176 if (IS_REGPARM (args->etype))
4177 addSymToBlock (args->sym, body);
4182 /*-----------------------------------------------------------------*/
4183 /* resetParmKey - resets the operandkeys for the symbols */
4184 /*-----------------------------------------------------------------*/
4185 DEFSETFUNC (resetParmKey)
4196 /*-----------------------------------------------------------------*/
4197 /* createFunction - This is the key node that calls the iCode for */
4198 /* generating the code for a function. Note code */
4199 /* is generated function by function, later when */
4200 /* add inter-procedural analysis this will change */
4201 /*-----------------------------------------------------------------*/
4203 createFunction (symbol * name, ast * body)
4209 iCode *piCode = NULL;
4211 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4212 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4214 /* if check function return 0 then some problem */
4215 if (checkFunction (name, NULL) == 0)
4218 /* create a dummy block if none exists */
4220 body = newNode (BLOCK, NULL, NULL);
4224 /* check if the function name already in the symbol table */
4225 if ((csym = findSym (SymbolTab, NULL, name->name)))
4228 /* special case for compiler defined functions
4229 we need to add the name to the publics list : this
4230 actually means we are now compiling the compiler
4234 addSet (&publics, name);
4240 allocVariables (name);
4242 name->lastLine = yylineno;
4245 /* set the stack pointer */
4246 /* PENDING: check this for the mcs51 */
4247 stackPtr = -port->stack.direction * port->stack.call_overhead;
4248 if (IFFUNC_ISISR (name->type))
4249 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4250 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4251 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4253 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4255 fetype = getSpec (name->type); /* get the specifier for the function */
4256 /* if this is a reentrant function then */
4257 if (IFFUNC_ISREENT (name->type))
4260 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4262 /* do processing for parameters that are passed in registers */
4263 processRegParms (FUNC_ARGS(name->type), body);
4265 /* set the stack pointer */
4269 /* allocate & autoinit the block variables */
4270 processBlockVars (body, &stack, ALLOCATE);
4272 /* save the stack information */
4273 if (options.useXstack)
4274 name->xstack = SPEC_STAK (fetype) = stack;
4276 name->stack = SPEC_STAK (fetype) = stack;
4278 /* name needs to be mangled */
4279 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4281 body = resolveSymbols (body); /* resolve the symbols */
4282 body = decorateType (body); /* propagateType & do semantic checks */
4284 ex = newAst_VALUE (symbolVal (name)); /* create name */
4285 ex = newNode (FUNCTION, ex, body);
4286 ex->values.args = FUNC_ARGS(name->type);
4288 if (options.dump_tree) PA(ex);
4291 werror (E_FUNC_NO_CODE, name->name);
4295 /* create the node & generate intermediate code */
4297 codeOutFile = code->oFile;
4298 piCode = iCodeFromAst (ex);
4302 werror (E_FUNC_NO_CODE, name->name);
4306 eBBlockFromiCode (piCode);
4308 /* if there are any statics then do them */
4311 GcurMemmap = statsg;
4312 codeOutFile = statsg->oFile;
4313 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4319 /* dealloc the block variables */
4320 processBlockVars (body, &stack, DEALLOCATE);
4321 /* deallocate paramaters */
4322 deallocParms (FUNC_ARGS(name->type));
4324 if (IFFUNC_ISREENT (name->type))
4327 /* we are done freeup memory & cleanup */
4329 if (port->reset_labelKey) labelKey = 1;
4331 FUNC_HASBODY(name->type) = 1;
4332 addSet (&operKeyReset, name);
4333 applyToSet (operKeyReset, resetParmKey);
4336 cdbStructBlock (1, cdbFile);
4338 cleanUpLevel (LabelTab, 0);
4339 cleanUpBlock (StructTab, 1);
4340 cleanUpBlock (TypedefTab, 1);
4342 xstack->syms = NULL;
4343 istack->syms = NULL;
4348 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4349 /*-----------------------------------------------------------------*/
4350 /* ast_print : prints the ast (for debugging purposes) */
4351 /*-----------------------------------------------------------------*/
4353 void ast_print (ast * tree, FILE *outfile, int indent)
4358 /* can print only decorated trees */
4359 if (!tree->decorated) return;
4361 /* if any child is an error | this one is an error do nothing */
4362 if (tree->isError ||
4363 (tree->left && tree->left->isError) ||
4364 (tree->right && tree->right->isError)) {
4365 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4369 /* print the line */
4370 /* if not block & function */
4371 if (tree->type == EX_OP &&
4372 (tree->opval.op != FUNCTION &&
4373 tree->opval.op != BLOCK &&
4374 tree->opval.op != NULLOP)) {
4377 if (tree->opval.op == FUNCTION) {
4379 value *args=FUNC_ARGS(tree->left->opval.val->type);
4380 fprintf(outfile,"FUNCTION (%s=%p) type (",
4381 tree->left->opval.val->name, tree);
4382 printTypeChain (tree->ftype,outfile);
4383 fprintf(outfile,") args (");
4386 fprintf (outfile, ", ");
4388 printTypeChain (args ? args->type : NULL, outfile);
4390 args= args ? args->next : NULL;
4392 fprintf(outfile,")\n");
4393 ast_print(tree->left,outfile,indent);
4394 ast_print(tree->right,outfile,indent);
4397 if (tree->opval.op == BLOCK) {
4398 symbol *decls = tree->values.sym;
4399 INDENT(indent,outfile);
4400 fprintf(outfile,"{\n");
4402 INDENT(indent+2,outfile);
4403 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4404 decls->name, decls);
4405 printTypeChain(decls->type,outfile);
4406 fprintf(outfile,")\n");
4408 decls = decls->next;
4410 ast_print(tree->right,outfile,indent+2);
4411 INDENT(indent,outfile);
4412 fprintf(outfile,"}\n");
4415 if (tree->opval.op == NULLOP) {
4416 fprintf(outfile,"\n");
4417 ast_print(tree->left,outfile,indent);
4418 fprintf(outfile,"\n");
4419 ast_print(tree->right,outfile,indent);
4422 INDENT(indent,outfile);
4424 /*------------------------------------------------------------------*/
4425 /*----------------------------*/
4426 /* leaf has been reached */
4427 /*----------------------------*/
4428 /* if this is of type value */
4429 /* just get the type */
4430 if (tree->type == EX_VALUE) {
4432 if (IS_LITERAL (tree->opval.val->etype)) {
4433 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4434 (int) floatFromVal(tree->opval.val),
4435 (int) floatFromVal(tree->opval.val),
4436 floatFromVal(tree->opval.val));
4437 } else if (tree->opval.val->sym) {
4438 /* if the undefined flag is set then give error message */
4439 if (tree->opval.val->sym->undefined) {
4440 fprintf(outfile,"UNDEFINED SYMBOL ");
4442 fprintf(outfile,"SYMBOL ");
4444 fprintf(outfile,"(%s=%p)",
4445 tree->opval.val->sym->name,tree);
4448 fprintf(outfile," type (");
4449 printTypeChain(tree->ftype,outfile);
4450 fprintf(outfile,")\n");
4452 fprintf(outfile,"\n");
4457 /* if type link for the case of cast */
4458 if (tree->type == EX_LINK) {
4459 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4460 printTypeChain(tree->opval.lnk,outfile);
4461 fprintf(outfile,")\n");
4466 /* depending on type of operator do */
4468 switch (tree->opval.op) {
4469 /*------------------------------------------------------------------*/
4470 /*----------------------------*/
4472 /*----------------------------*/
4474 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4475 printTypeChain(tree->ftype,outfile);
4476 fprintf(outfile,")\n");
4477 ast_print(tree->left,outfile,indent+2);
4478 ast_print(tree->right,outfile,indent+2);
4481 /*------------------------------------------------------------------*/
4482 /*----------------------------*/
4484 /*----------------------------*/
4486 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4487 printTypeChain(tree->ftype,outfile);
4488 fprintf(outfile,")\n");
4489 ast_print(tree->left,outfile,indent+2);
4490 ast_print(tree->right,outfile,indent+2);
4493 /*------------------------------------------------------------------*/
4494 /*----------------------------*/
4495 /* struct/union pointer */
4496 /*----------------------------*/
4498 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4499 printTypeChain(tree->ftype,outfile);
4500 fprintf(outfile,")\n");
4501 ast_print(tree->left,outfile,indent+2);
4502 ast_print(tree->right,outfile,indent+2);
4505 /*------------------------------------------------------------------*/
4506 /*----------------------------*/
4507 /* ++/-- operation */
4508 /*----------------------------*/
4509 case INC_OP: /* incerement operator unary so left only */
4510 fprintf(outfile,"INC_OP (%p) type (",tree);
4511 printTypeChain(tree->ftype,outfile);
4512 fprintf(outfile,")\n");
4513 ast_print(tree->left,outfile,indent+2);
4517 fprintf(outfile,"DEC_OP (%p) type (",tree);
4518 printTypeChain(tree->ftype,outfile);
4519 fprintf(outfile,")\n");
4520 ast_print(tree->left,outfile,indent+2);
4523 /*------------------------------------------------------------------*/
4524 /*----------------------------*/
4526 /*----------------------------*/
4529 fprintf(outfile,"& (%p) type (",tree);
4530 printTypeChain(tree->ftype,outfile);
4531 fprintf(outfile,")\n");
4532 ast_print(tree->left,outfile,indent+2);
4533 ast_print(tree->right,outfile,indent+2);
4535 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4536 printTypeChain(tree->ftype,outfile);
4537 fprintf(outfile,")\n");
4538 ast_print(tree->left,outfile,indent+2);
4539 ast_print(tree->right,outfile,indent+2);
4542 /*----------------------------*/
4544 /*----------------------------*/
4546 fprintf(outfile,"OR (%p) type (",tree);
4547 printTypeChain(tree->ftype,outfile);
4548 fprintf(outfile,")\n");
4549 ast_print(tree->left,outfile,indent+2);
4550 ast_print(tree->right,outfile,indent+2);
4552 /*------------------------------------------------------------------*/
4553 /*----------------------------*/
4555 /*----------------------------*/
4557 fprintf(outfile,"XOR (%p) type (",tree);
4558 printTypeChain(tree->ftype,outfile);
4559 fprintf(outfile,")\n");
4560 ast_print(tree->left,outfile,indent+2);
4561 ast_print(tree->right,outfile,indent+2);
4564 /*------------------------------------------------------------------*/
4565 /*----------------------------*/
4567 /*----------------------------*/
4569 fprintf(outfile,"DIV (%p) type (",tree);
4570 printTypeChain(tree->ftype,outfile);
4571 fprintf(outfile,")\n");
4572 ast_print(tree->left,outfile,indent+2);
4573 ast_print(tree->right,outfile,indent+2);
4575 /*------------------------------------------------------------------*/
4576 /*----------------------------*/
4578 /*----------------------------*/
4580 fprintf(outfile,"MOD (%p) type (",tree);
4581 printTypeChain(tree->ftype,outfile);
4582 fprintf(outfile,")\n");
4583 ast_print(tree->left,outfile,indent+2);
4584 ast_print(tree->right,outfile,indent+2);
4587 /*------------------------------------------------------------------*/
4588 /*----------------------------*/
4589 /* address dereference */
4590 /*----------------------------*/
4591 case '*': /* can be unary : if right is null then unary operation */
4593 fprintf(outfile,"DEREF (%p) type (",tree);
4594 printTypeChain(tree->ftype,outfile);
4595 fprintf(outfile,")\n");
4596 ast_print(tree->left,outfile,indent+2);
4599 /*------------------------------------------------------------------*/
4600 /*----------------------------*/
4601 /* multiplication */
4602 /*----------------------------*/
4603 fprintf(outfile,"MULT (%p) type (",tree);
4604 printTypeChain(tree->ftype,outfile);
4605 fprintf(outfile,")\n");
4606 ast_print(tree->left,outfile,indent+2);
4607 ast_print(tree->right,outfile,indent+2);
4611 /*------------------------------------------------------------------*/
4612 /*----------------------------*/
4613 /* unary '+' operator */
4614 /*----------------------------*/
4618 fprintf(outfile,"UPLUS (%p) type (",tree);
4619 printTypeChain(tree->ftype,outfile);
4620 fprintf(outfile,")\n");
4621 ast_print(tree->left,outfile,indent+2);
4623 /*------------------------------------------------------------------*/
4624 /*----------------------------*/
4626 /*----------------------------*/
4627 fprintf(outfile,"ADD (%p) type (",tree);
4628 printTypeChain(tree->ftype,outfile);
4629 fprintf(outfile,")\n");
4630 ast_print(tree->left,outfile,indent+2);
4631 ast_print(tree->right,outfile,indent+2);
4634 /*------------------------------------------------------------------*/
4635 /*----------------------------*/
4637 /*----------------------------*/
4638 case '-': /* can be unary */
4640 fprintf(outfile,"UMINUS (%p) type (",tree);
4641 printTypeChain(tree->ftype,outfile);
4642 fprintf(outfile,")\n");
4643 ast_print(tree->left,outfile,indent+2);
4645 /*------------------------------------------------------------------*/
4646 /*----------------------------*/
4648 /*----------------------------*/
4649 fprintf(outfile,"SUB (%p) type (",tree);
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->left,outfile,indent+2);
4653 ast_print(tree->right,outfile,indent+2);
4656 /*------------------------------------------------------------------*/
4657 /*----------------------------*/
4659 /*----------------------------*/
4661 fprintf(outfile,"COMPL (%p) type (",tree);
4662 printTypeChain(tree->ftype,outfile);
4663 fprintf(outfile,")\n");
4664 ast_print(tree->left,outfile,indent+2);
4666 /*------------------------------------------------------------------*/
4667 /*----------------------------*/
4669 /*----------------------------*/
4671 fprintf(outfile,"NOT (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+2);
4676 /*------------------------------------------------------------------*/
4677 /*----------------------------*/
4679 /*----------------------------*/
4681 fprintf(outfile,"RRC (%p) type (",tree);
4682 printTypeChain(tree->ftype,outfile);
4683 fprintf(outfile,")\n");
4684 ast_print(tree->left,outfile,indent+2);
4688 fprintf(outfile,"RLC (%p) type (",tree);
4689 printTypeChain(tree->ftype,outfile);
4690 fprintf(outfile,")\n");
4691 ast_print(tree->left,outfile,indent+2);
4694 fprintf(outfile,"GETHBIT (%p) type (",tree);
4695 printTypeChain(tree->ftype,outfile);
4696 fprintf(outfile,")\n");
4697 ast_print(tree->left,outfile,indent+2);
4700 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4701 printTypeChain(tree->ftype,outfile);
4702 fprintf(outfile,")\n");
4703 ast_print(tree->left,outfile,indent+2);
4704 ast_print(tree->right,outfile,indent+2);
4707 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4708 printTypeChain(tree->ftype,outfile);
4709 fprintf(outfile,")\n");
4710 ast_print(tree->left,outfile,indent+2);
4711 ast_print(tree->right,outfile,indent+2);
4713 /*------------------------------------------------------------------*/
4714 /*----------------------------*/
4716 /*----------------------------*/
4717 case CAST: /* change the type */
4718 fprintf(outfile,"CAST (%p) from type (",tree);
4719 printTypeChain(tree->right->ftype,outfile);
4720 fprintf(outfile,") to type (");
4721 printTypeChain(tree->ftype,outfile);
4722 fprintf(outfile,")\n");
4723 ast_print(tree->right,outfile,indent+2);
4727 fprintf(outfile,"ANDAND (%p) type (",tree);
4728 printTypeChain(tree->ftype,outfile);
4729 fprintf(outfile,")\n");
4730 ast_print(tree->left,outfile,indent+2);
4731 ast_print(tree->right,outfile,indent+2);
4734 fprintf(outfile,"OROR (%p) type (",tree);
4735 printTypeChain(tree->ftype,outfile);
4736 fprintf(outfile,")\n");
4737 ast_print(tree->left,outfile,indent+2);
4738 ast_print(tree->right,outfile,indent+2);
4741 /*------------------------------------------------------------------*/
4742 /*----------------------------*/
4743 /* comparison operators */
4744 /*----------------------------*/
4746 fprintf(outfile,"GT(>) (%p) type (",tree);
4747 printTypeChain(tree->ftype,outfile);
4748 fprintf(outfile,")\n");
4749 ast_print(tree->left,outfile,indent+2);
4750 ast_print(tree->right,outfile,indent+2);
4753 fprintf(outfile,"LT(<) (%p) type (",tree);
4754 printTypeChain(tree->ftype,outfile);
4755 fprintf(outfile,")\n");
4756 ast_print(tree->left,outfile,indent+2);
4757 ast_print(tree->right,outfile,indent+2);
4760 fprintf(outfile,"LE(<=) (%p) type (",tree);
4761 printTypeChain(tree->ftype,outfile);
4762 fprintf(outfile,")\n");
4763 ast_print(tree->left,outfile,indent+2);
4764 ast_print(tree->right,outfile,indent+2);
4767 fprintf(outfile,"GE(>=) (%p) type (",tree);
4768 printTypeChain(tree->ftype,outfile);
4769 fprintf(outfile,")\n");
4770 ast_print(tree->left,outfile,indent+2);
4771 ast_print(tree->right,outfile,indent+2);
4774 fprintf(outfile,"EQ(==) (%p) type (",tree);
4775 printTypeChain(tree->ftype,outfile);
4776 fprintf(outfile,")\n");
4777 ast_print(tree->left,outfile,indent+2);
4778 ast_print(tree->right,outfile,indent+2);
4781 fprintf(outfile,"NE(!=) (%p) type (",tree);
4782 printTypeChain(tree->ftype,outfile);
4783 fprintf(outfile,")\n");
4784 ast_print(tree->left,outfile,indent+2);
4785 ast_print(tree->right,outfile,indent+2);
4786 /*------------------------------------------------------------------*/
4787 /*----------------------------*/
4789 /*----------------------------*/
4790 case SIZEOF: /* evaluate wihout code generation */
4791 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4794 /*------------------------------------------------------------------*/
4795 /*----------------------------*/
4796 /* conditional operator '?' */
4797 /*----------------------------*/
4799 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4800 printTypeChain(tree->ftype,outfile);
4801 fprintf(outfile,")\n");
4802 ast_print(tree->left,outfile,indent+2);
4803 ast_print(tree->right,outfile,indent+2);
4807 fprintf(outfile,"COLON(:) (%p) type (",tree);
4808 printTypeChain(tree->ftype,outfile);
4809 fprintf(outfile,")\n");
4810 ast_print(tree->left,outfile,indent+2);
4811 ast_print(tree->right,outfile,indent+2);
4814 /*------------------------------------------------------------------*/
4815 /*----------------------------*/
4816 /* assignment operators */
4817 /*----------------------------*/
4819 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4820 printTypeChain(tree->ftype,outfile);
4821 fprintf(outfile,")\n");
4822 ast_print(tree->left,outfile,indent+2);
4823 ast_print(tree->right,outfile,indent+2);
4826 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4827 printTypeChain(tree->ftype,outfile);
4828 fprintf(outfile,")\n");
4829 ast_print(tree->left,outfile,indent+2);
4830 ast_print(tree->right,outfile,indent+2);
4833 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4834 printTypeChain(tree->ftype,outfile);
4835 fprintf(outfile,")\n");
4836 ast_print(tree->left,outfile,indent+2);
4837 ast_print(tree->right,outfile,indent+2);
4840 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4841 printTypeChain(tree->ftype,outfile);
4842 fprintf(outfile,")\n");
4843 ast_print(tree->left,outfile,indent+2);
4844 ast_print(tree->right,outfile,indent+2);
4847 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4848 printTypeChain(tree->ftype,outfile);
4849 fprintf(outfile,")\n");
4850 ast_print(tree->left,outfile,indent+2);
4851 ast_print(tree->right,outfile,indent+2);
4854 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4855 printTypeChain(tree->ftype,outfile);
4856 fprintf(outfile,")\n");
4857 ast_print(tree->left,outfile,indent+2);
4858 ast_print(tree->right,outfile,indent+2);
4861 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4862 printTypeChain(tree->ftype,outfile);
4863 fprintf(outfile,")\n");
4864 ast_print(tree->left,outfile,indent+2);
4865 ast_print(tree->right,outfile,indent+2);
4867 /*------------------------------------------------------------------*/
4868 /*----------------------------*/
4870 /*----------------------------*/
4872 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4873 printTypeChain(tree->ftype,outfile);
4874 fprintf(outfile,")\n");
4875 ast_print(tree->left,outfile,indent+2);
4876 ast_print(tree->right,outfile,indent+2);
4878 /*------------------------------------------------------------------*/
4879 /*----------------------------*/
4881 /*----------------------------*/
4883 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4884 printTypeChain(tree->ftype,outfile);
4885 fprintf(outfile,")\n");
4886 ast_print(tree->left,outfile,indent+2);
4887 ast_print(tree->right,outfile,indent+2);
4889 /*------------------------------------------------------------------*/
4890 /*----------------------------*/
4891 /* straight assignemnt */
4892 /*----------------------------*/
4894 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4895 printTypeChain(tree->ftype,outfile);
4896 fprintf(outfile,")\n");
4897 ast_print(tree->left,outfile,indent+2);
4898 ast_print(tree->right,outfile,indent+2);
4900 /*------------------------------------------------------------------*/
4901 /*----------------------------*/
4902 /* comma operator */
4903 /*----------------------------*/
4905 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4906 printTypeChain(tree->ftype,outfile);
4907 fprintf(outfile,")\n");
4908 ast_print(tree->left,outfile,indent+2);
4909 ast_print(tree->right,outfile,indent+2);
4911 /*------------------------------------------------------------------*/
4912 /*----------------------------*/
4914 /*----------------------------*/
4917 fprintf(outfile,"CALL (%p) type (",tree);
4918 printTypeChain(tree->ftype,outfile);
4919 fprintf(outfile,")\n");
4920 ast_print(tree->left,outfile,indent+2);
4921 ast_print(tree->right,outfile,indent+2);
4924 fprintf(outfile,"PARMS\n");
4925 ast_print(tree->left,outfile,indent+2);
4926 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4927 ast_print(tree->right,outfile,indent+2);
4930 /*------------------------------------------------------------------*/
4931 /*----------------------------*/
4932 /* return statement */
4933 /*----------------------------*/
4935 fprintf(outfile,"RETURN (%p) type (",tree);
4937 printTypeChain(tree->right->ftype,outfile);
4939 fprintf(outfile,")\n");
4940 ast_print(tree->right,outfile,indent+2);
4942 /*------------------------------------------------------------------*/
4943 /*----------------------------*/
4944 /* label statement */
4945 /*----------------------------*/
4947 fprintf(outfile,"LABEL (%p)\n",tree);
4948 ast_print(tree->left,outfile,indent+2);
4949 ast_print(tree->right,outfile,indent);
4951 /*------------------------------------------------------------------*/
4952 /*----------------------------*/
4953 /* switch statement */
4954 /*----------------------------*/
4958 fprintf(outfile,"SWITCH (%p) ",tree);
4959 ast_print(tree->left,outfile,0);
4960 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4961 INDENT(indent+2,outfile);
4962 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4963 (int) floatFromVal(val),
4964 tree->values.switchVals.swNum,
4965 (int) floatFromVal(val));
4967 ast_print(tree->right,outfile,indent);
4970 /*------------------------------------------------------------------*/
4971 /*----------------------------*/
4973 /*----------------------------*/
4975 fprintf(outfile,"IF (%p) \n",tree);
4976 ast_print(tree->left,outfile,indent+2);
4977 if (tree->trueLabel) {
4978 INDENT(indent,outfile);
4979 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4981 if (tree->falseLabel) {
4982 INDENT(indent,outfile);
4983 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4985 ast_print(tree->right,outfile,indent+2);
4987 /*------------------------------------------------------------------*/
4988 /*----------------------------*/
4990 /*----------------------------*/
4992 fprintf(outfile,"FOR (%p) \n",tree);
4993 if (AST_FOR( tree, initExpr)) {
4994 INDENT(indent+2,outfile);
4995 fprintf(outfile,"INIT EXPR ");
4996 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4998 if (AST_FOR( tree, condExpr)) {
4999 INDENT(indent+2,outfile);
5000 fprintf(outfile,"COND EXPR ");
5001 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5003 if (AST_FOR( tree, loopExpr)) {
5004 INDENT(indent+2,outfile);
5005 fprintf(outfile,"LOOP EXPR ");
5006 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5008 fprintf(outfile,"FOR LOOP BODY \n");
5009 ast_print(tree->left,outfile,indent+2);
5018 ast_print(t,stdout,0);