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
50 symbol *currFunc=NULL;
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 *optimizeSWAP (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
60 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
65 printTypeChain (tree->ftype, stdout);
70 /*-----------------------------------------------------------------*/
71 /* newAst - creates a fresh node for an expression tree */
72 /*-----------------------------------------------------------------*/
74 newAst_ (unsigned type)
77 static int oldLineno = 0;
79 ex = Safe_alloc ( sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : mylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
91 newAst_VALUE (value * val)
93 ast *ex = newAst_ (EX_VALUE);
99 newAst_OP (unsigned op)
101 ast *ex = newAst_ (EX_OP);
107 newAst_LINK (sym_link * val)
109 ast *ex = newAst_ (EX_LINK);
114 /*-----------------------------------------------------------------*/
115 /* newNode - creates a new node */
116 /*-----------------------------------------------------------------*/
118 newNode (long op, ast * left, ast * right)
129 /*-----------------------------------------------------------------*/
130 /* newIfxNode - creates a new Ifx Node */
131 /*-----------------------------------------------------------------*/
133 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
137 /* if this is a literal then we already know the result */
138 if (condAst->etype && IS_LITERAL (condAst->etype))
140 /* then depending on the expression value */
141 if (floatFromVal (condAst->opval.val))
142 ifxNode = newNode (GOTO,
143 newAst_VALUE (symbolVal (trueLabel)),
146 ifxNode = newNode (GOTO,
147 newAst_VALUE (symbolVal (falseLabel)),
152 ifxNode = newNode (IFX, condAst, NULL);
153 ifxNode->trueLabel = trueLabel;
154 ifxNode->falseLabel = falseLabel;
160 /*-----------------------------------------------------------------*/
161 /* copyAstValues - copies value portion of ast if needed */
162 /*-----------------------------------------------------------------*/
164 copyAstValues (ast * dest, ast * src)
166 switch (src->opval.op)
169 dest->values.sym = copySymbolChain (src->values.sym);
173 dest->values.switchVals.swVals =
174 copyValue (src->values.switchVals.swVals);
175 dest->values.switchVals.swDefault =
176 src->values.switchVals.swDefault;
177 dest->values.switchVals.swNum =
178 src->values.switchVals.swNum;
182 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
186 dest->values.constlist = copyLiteralList(src->values.constlist);
190 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
191 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
192 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
193 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
194 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
195 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
196 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
201 /*-----------------------------------------------------------------*/
202 /* copyAst - makes a copy of a given astession */
203 /*-----------------------------------------------------------------*/
212 dest = Safe_alloc ( sizeof (ast));
214 dest->type = src->type;
215 dest->lineno = src->lineno;
216 dest->level = src->level;
217 dest->funcName = src->funcName;
220 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
222 /* if this is a leaf */
224 if (src->type == EX_VALUE)
226 dest->opval.val = copyValue (src->opval.val);
231 if (src->type == EX_LINK)
233 dest->opval.lnk = copyLinkChain (src->opval.lnk);
237 dest->opval.op = src->opval.op;
239 /* if this is a node that has special values */
240 copyAstValues (dest, src);
242 dest->trueLabel = copySymbol (src->trueLabel);
243 dest->falseLabel = copySymbol (src->falseLabel);
244 dest->left = copyAst (src->left);
245 dest->right = copyAst (src->right);
251 /*-----------------------------------------------------------------*/
252 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
253 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
254 /*-----------------------------------------------------------------*/
255 ast *removeIncDecOps (ast * tree) {
257 // traverse the tree and remove inc/dec ops
262 if (tree->type == EX_OP &&
263 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
270 tree->left=removeIncDecOps(tree->left);
271 tree->right=removeIncDecOps(tree->right);
276 /*-----------------------------------------------------------------*/
277 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
278 /* "*++s += 3" -> "*++s = *++s + 3" */
279 /*-----------------------------------------------------------------*/
280 ast *removePreIncDecOps (ast * tree) {
282 // traverse the tree and remove pre-inc/dec ops
287 if (tree->type == EX_OP &&
288 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
293 tree->left=removePreIncDecOps(tree->left);
294 tree->right=removePreIncDecOps(tree->right);
299 /*-----------------------------------------------------------------*/
300 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
301 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
302 /*-----------------------------------------------------------------*/
303 ast *removePostIncDecOps (ast * tree) {
305 // traverse the tree and remove pre-inc/dec ops
310 if (tree->type == EX_OP &&
311 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
316 tree->left=removePostIncDecOps(tree->left);
317 tree->right=removePostIncDecOps(tree->right);
322 /*-----------------------------------------------------------------*/
323 /* hasSEFcalls - returns TRUE if tree has a function call */
324 /*-----------------------------------------------------------------*/
326 hasSEFcalls (ast * tree)
331 if (tree->type == EX_OP &&
332 (tree->opval.op == CALL ||
333 tree->opval.op == PCALL ||
334 tree->opval.op == '=' ||
335 tree->opval.op == INC_OP ||
336 tree->opval.op == DEC_OP))
339 return (hasSEFcalls (tree->left) |
340 hasSEFcalls (tree->right));
343 /*-----------------------------------------------------------------*/
344 /* isAstEqual - compares two asts & returns 1 if they are equal */
345 /*-----------------------------------------------------------------*/
347 isAstEqual (ast * t1, ast * t2)
356 if (t1->type != t2->type)
362 if (t1->opval.op != t2->opval.op)
364 return (isAstEqual (t1->left, t2->left) &&
365 isAstEqual (t1->right, t2->right));
369 if (t1->opval.val->sym)
371 if (!t2->opval.val->sym)
374 return isSymbolEqual (t1->opval.val->sym,
379 if (t2->opval.val->sym)
382 return (floatFromVal (t1->opval.val) ==
383 floatFromVal (t2->opval.val));
387 /* only compare these two types */
395 /*-----------------------------------------------------------------*/
396 /* resolveSymbols - resolve symbols from the symbol table */
397 /*-----------------------------------------------------------------*/
399 resolveSymbols (ast * tree)
401 /* walk the entire tree and check for values */
402 /* with symbols if we find one then replace */
403 /* symbol with that from the symbol table */
410 /* if not block & function */
411 if (tree->type == EX_OP &&
412 (tree->opval.op != FUNCTION &&
413 tree->opval.op != BLOCK &&
414 tree->opval.op != NULLOP))
416 filename = tree->filename;
417 lineno = tree->lineno;
421 /* make sure we resolve the true & false labels for ifx */
422 if (tree->type == EX_OP && tree->opval.op == IFX)
428 if ((csym = findSym (LabelTab, tree->trueLabel,
429 tree->trueLabel->name)))
430 tree->trueLabel = csym;
432 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
433 tree->trueLabel->name);
436 if (tree->falseLabel)
438 if ((csym = findSym (LabelTab,
440 tree->falseLabel->name)))
441 tree->falseLabel = csym;
443 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
444 tree->falseLabel->name);
449 /* if this is a label resolve it from the labelTab */
450 if (IS_AST_VALUE (tree) &&
451 tree->opval.val->sym &&
452 tree->opval.val->sym->islbl)
455 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
456 tree->opval.val->sym->name);
459 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
460 tree->opval.val->sym->name);
462 tree->opval.val->sym = csym;
464 goto resolveChildren;
467 /* do only for leafs */
468 if (IS_AST_VALUE (tree) &&
469 tree->opval.val->sym &&
470 !tree->opval.val->sym->implicit)
473 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
475 /* if found in the symbol table & they r not the same */
476 if (csym && tree->opval.val->sym != csym)
478 tree->opval.val->sym = csym;
479 tree->opval.val->type = csym->type;
480 tree->opval.val->etype = csym->etype;
483 /* if not found in the symbol table */
484 /* mark it as undefined assume it is */
485 /* an integer in data space */
486 if (!csym && !tree->opval.val->sym->implicit)
489 /* if this is a function name then */
490 /* mark it as returning an int */
493 tree->opval.val->sym->type = newLink (DECLARATOR);
494 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
495 tree->opval.val->sym->type->next =
496 tree->opval.val->sym->etype = newIntLink ();
497 tree->opval.val->etype = tree->opval.val->etype;
498 tree->opval.val->type = tree->opval.val->sym->type;
499 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
500 tree->opval.val->sym->name);
501 //tree->opval.val->sym->undefined = 1;
502 allocVariables (tree->opval.val->sym);
506 tree->opval.val->sym->undefined = 1;
507 tree->opval.val->type =
508 tree->opval.val->etype = newIntLink ();
509 tree->opval.val->sym->type =
510 tree->opval.val->sym->etype = newIntLink ();
516 resolveSymbols (tree->left);
517 resolveSymbols (tree->right);
522 /*-----------------------------------------------------------------*/
523 /* setAstLineno - walks a ast tree & sets the line number */
524 /*-----------------------------------------------------------------*/
525 int setAstLineno (ast * tree, int lineno)
530 tree->lineno = lineno;
531 setAstLineno (tree->left, lineno);
532 setAstLineno (tree->right, lineno);
536 /*-----------------------------------------------------------------*/
537 /* funcOfType :- function of type with name */
538 /*-----------------------------------------------------------------*/
540 funcOfType (char *name, sym_link * type, sym_link * argType,
544 /* create the symbol */
545 sym = newSymbol (name, 0);
547 /* setup return value */
548 sym->type = newLink (DECLARATOR);
549 DCL_TYPE (sym->type) = FUNCTION;
550 sym->type->next = copyLinkChain (type);
551 sym->etype = getSpec (sym->type);
552 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
554 /* if arguments required */
558 args = FUNC_ARGS(sym->type) = newValue ();
562 args->type = copyLinkChain (argType);
563 args->etype = getSpec (args->type);
564 SPEC_EXTR(args->etype)=1;
567 args = args->next = newValue ();
574 allocVariables (sym);
579 /*-----------------------------------------------------------------*/
580 /* funcOfTypeVarg :- function of type with name and argtype */
581 /*-----------------------------------------------------------------*/
583 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
588 /* create the symbol */
589 sym = newSymbol (name, 0);
591 /* setup return value */
592 sym->type = newLink (DECLARATOR);
593 DCL_TYPE (sym->type) = FUNCTION;
594 sym->type->next = typeFromStr(rtype);
595 sym->etype = getSpec (sym->type);
597 /* if arguments required */
600 args = FUNC_ARGS(sym->type) = newValue ();
602 for ( i = 0 ; i < nArgs ; i++ ) {
603 args->type = typeFromStr(atypes[i]);
604 args->etype = getSpec (args->type);
605 SPEC_EXTR(args->etype)=1;
606 if ((i + 1) == nArgs) break;
607 args = args->next = newValue ();
614 allocVariables (sym);
619 /*-----------------------------------------------------------------*/
620 /* reverseParms - will reverse a parameter tree */
621 /*-----------------------------------------------------------------*/
623 reverseParms (ast * ptree)
629 /* top down if we find a nonParm tree then quit */
630 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
633 ptree->left = ptree->right;
634 ptree->right = ttree;
635 reverseParms (ptree->left);
636 reverseParms (ptree->right);
642 /*-----------------------------------------------------------------*/
643 /* processParms - makes sure the parameters are okay and do some */
644 /* processing with them */
645 /*-----------------------------------------------------------------*/
647 processParms (ast * func,
650 int *parmNumber, // unused, although updated
653 /* if none of them exist */
654 if (!defParm && !actParm)
658 if (getenv("DEBUG_SANITY")) {
659 fprintf (stderr, "processParms: %s ", defParm->name);
661 /* make sure the type is complete and sane */
662 checkTypeSanity(defParm->etype, defParm->name);
665 /* if the function is being called via a pointer & */
666 /* it has not been defined a reentrant then we cannot */
667 /* have parameters */
668 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
670 werror (W_NONRENT_ARGS);
674 /* if defined parameters ended but actual parameters */
675 /* exist and this is not defined as a variable arg */
676 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
678 //if (func->type==EX_VALUE && func->opval.val->sym->undefined)
679 // return 1; /* Already gave them an undefined function error */
680 werror (E_TOO_MANY_PARMS);
684 /* if defined parameters present but no actual parameters */
685 if (defParm && !actParm)
687 werror (E_TOO_FEW_PARMS);
691 if (IS_VOID(actParm->ftype)) {
692 werror (E_VOID_VALUE_USED);
696 /* If this is a varargs function... */
697 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
702 if (IS_CAST_OP (actParm)
703 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
705 /* Parameter was explicitly typecast; don't touch it. */
709 ftype = actParm->ftype;
711 /* If it's a small integer, upcast to int. */
712 if (IS_INTEGRAL (ftype)
713 && (getSize (ftype) < (unsigned) INTSIZE))
715 if (IS_AST_OP(actParm) &&
716 (actParm->opval.op == LEFT_OP ||
717 actParm->opval.op == '*' ||
718 actParm->opval.op == '+' ||
719 actParm->opval.op == '-') &&
721 // we should cast an operand instead of the result
722 actParm->decorated = 0;
723 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
725 actParm = decorateType(actParm);
727 newType = newAst_LINK(INTTYPE);
731 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
733 newType = newAst_LINK (copyLinkChain(ftype));
734 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
737 if (IS_AGGREGATE (ftype))
739 newType = newAst_LINK (copyLinkChain (ftype));
740 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
744 /* cast required; change this op to a cast. */
745 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
747 actParm->type = EX_OP;
748 actParm->opval.op = CAST;
749 actParm->left = newType;
750 actParm->right = parmCopy;
751 decorateType (actParm);
753 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
755 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
756 processParms (func, NULL, actParm->right, parmNumber, rightmost));
761 /* if defined parameters ended but actual has not & */
763 if (!defParm && actParm &&
764 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
767 resolveSymbols (actParm);
768 /* if this is a PARAM node then match left & right */
769 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
771 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
772 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
776 /* If we have found a value node by following only right-hand links,
777 * then we know that there are no more values after us.
779 * Therefore, if there are more defined parameters, the caller didn't
782 if (rightmost && defParm->next)
784 werror (E_TOO_FEW_PARMS);
789 /* the parameter type must be at least castable */
790 if (compareType (defParm->type, actParm->ftype) == 0) {
791 werror (E_INCOMPAT_TYPES);
792 printFromToType (actParm->ftype, defParm->type);
796 /* if the parameter is castable then add the cast */
797 if (compareType (defParm->type, actParm->ftype) < 0)
799 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
801 /* now change the current one to a cast */
802 actParm->type = EX_OP;
803 actParm->opval.op = CAST;
804 actParm->left = newAst_LINK (defParm->type);
805 actParm->right = pTree;
806 actParm->etype = defParm->etype;
807 actParm->ftype = defParm->type;
808 actParm->decorated=0; /* force typechecking */
809 decorateType (actParm);
812 /* make a copy and change the regparm type to the defined parm */
813 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
814 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
815 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
819 /*-----------------------------------------------------------------*/
820 /* createIvalType - generates ival for basic types */
821 /*-----------------------------------------------------------------*/
823 createIvalType (ast * sym, sym_link * type, initList * ilist)
827 /* if initList is deep */
828 if (ilist->type == INIT_DEEP)
829 ilist = ilist->init.deep;
831 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
832 return decorateType (newNode ('=', sym, iExpr));
835 /*-----------------------------------------------------------------*/
836 /* createIvalStruct - generates initial value for structures */
837 /*-----------------------------------------------------------------*/
839 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
846 sflds = SPEC_STRUCT (type)->fields;
847 if (ilist->type != INIT_DEEP)
849 werror (E_INIT_STRUCT, "");
853 iloop = ilist->init.deep;
855 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
857 /* if we have come to end */
861 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
862 lAst = decorateType (resolveSymbols (lAst));
863 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
867 werrorfl (filename, sym->opval.val->sym->lineDef,
868 W_EXCESS_INITIALIZERS, "struct",
869 sym->opval.val->sym->name);
876 /*-----------------------------------------------------------------*/
877 /* createIvalArray - generates code for array initialization */
878 /*-----------------------------------------------------------------*/
880 createIvalArray (ast * sym, sym_link * type, initList * ilist)
884 int lcnt = 0, size = 0;
885 literalList *literalL;
887 /* take care of the special case */
888 /* array of characters can be init */
890 if (IS_CHAR (type->next))
891 if ((rast = createIvalCharPtr (sym,
893 decorateType (resolveSymbols (list2expr (ilist))))))
895 return decorateType (resolveSymbols (rast));
897 /* not the special case */
898 if (ilist->type != INIT_DEEP)
900 werror (E_INIT_STRUCT, "");
904 iloop = ilist->init.deep;
905 lcnt = DCL_ELEM (type);
907 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
911 aSym = decorateType (resolveSymbols(sym));
913 rast = newNode(ARRAYINIT, aSym, NULL);
914 rast->values.constlist = literalL;
916 // Make sure size is set to length of initializer list.
923 if (lcnt && size > lcnt)
925 // Array size was specified, and we have more initializers than needed.
926 char *name=sym->opval.val->sym->name;
927 int lineno=sym->opval.val->sym->lineDef;
929 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
938 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
939 aSym = decorateType (resolveSymbols (aSym));
940 rast = createIval (aSym, type->next, iloop, rast);
941 iloop = (iloop ? iloop->next : NULL);
947 /* no of elements given and we */
948 /* have generated for all of them */
951 // there has to be a better way
952 char *name=sym->opval.val->sym->name;
953 int lineno=sym->opval.val->sym->lineDef;
954 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
961 /* if we have not been given a size */
962 if (!DCL_ELEM (type))
964 DCL_ELEM (type) = size;
967 return decorateType (resolveSymbols (rast));
971 /*-----------------------------------------------------------------*/
972 /* createIvalCharPtr - generates initial values for char pointers */
973 /*-----------------------------------------------------------------*/
975 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
979 /* if this is a pointer & right is a literal array then */
980 /* just assignment will do */
981 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
982 SPEC_SCLS (iexpr->etype) == S_CODE)
983 && IS_ARRAY (iexpr->ftype)))
984 return newNode ('=', sym, iexpr);
986 /* left side is an array so we have to assign each */
988 if ((IS_LITERAL (iexpr->etype) ||
989 SPEC_SCLS (iexpr->etype) == S_CODE)
990 && IS_ARRAY (iexpr->ftype))
992 /* for each character generate an assignment */
993 /* to the array element */
994 char *s = SPEC_CVAL (iexpr->etype).v_char;
996 int size = getSize (iexpr->ftype);
997 int symsize = getSize (type);
1001 if (size>(symsize+1))
1002 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1003 "string", sym->opval.val->sym->name);
1007 for (i=0;i<size;i++)
1009 rast = newNode (NULLOP,
1013 newAst_VALUE (valueFromLit ((float) i))),
1014 newAst_VALUE (valueFromLit (*s))));
1018 // now WE don't need iexpr's symbol anymore
1019 freeStringSymbol(AST_SYMBOL(iexpr));
1021 return decorateType (resolveSymbols (rast));
1027 /*-----------------------------------------------------------------*/
1028 /* createIvalPtr - generates initial value for pointers */
1029 /*-----------------------------------------------------------------*/
1031 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1037 if (ilist->type == INIT_DEEP)
1038 ilist = ilist->init.deep;
1040 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1042 /* if character pointer */
1043 if (IS_CHAR (type->next))
1044 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1047 return newNode ('=', sym, iexpr);
1050 /*-----------------------------------------------------------------*/
1051 /* createIval - generates code for initial value */
1052 /*-----------------------------------------------------------------*/
1054 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1061 /* if structure then */
1062 if (IS_STRUCT (type))
1063 rast = createIvalStruct (sym, type, ilist);
1065 /* if this is a pointer */
1067 rast = createIvalPtr (sym, type, ilist);
1069 /* if this is an array */
1070 if (IS_ARRAY (type))
1071 rast = createIvalArray (sym, type, ilist);
1073 /* if type is SPECIFIER */
1075 rast = createIvalType (sym, type, ilist);
1078 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1080 return decorateType (resolveSymbols (rast));
1083 /*-----------------------------------------------------------------*/
1084 /* initAggregates - initialises aggregate variables with initv */
1085 /*-----------------------------------------------------------------*/
1086 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1087 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1090 /*-----------------------------------------------------------------*/
1091 /* gatherAutoInit - creates assignment expressions for initial */
1093 /*-----------------------------------------------------------------*/
1095 gatherAutoInit (symbol * autoChain)
1102 for (sym = autoChain; sym; sym = sym->next)
1105 /* resolve the symbols in the ival */
1107 resolveIvalSym (sym->ival);
1109 /* if this is a static variable & has an */
1110 /* initial value the code needs to be lifted */
1111 /* here to the main portion since they can be */
1112 /* initialised only once at the start */
1113 if (IS_STATIC (sym->etype) && sym->ival &&
1114 SPEC_SCLS (sym->etype) != S_CODE)
1118 /* insert the symbol into the symbol table */
1119 /* with level = 0 & name = rname */
1120 newSym = copySymbol (sym);
1121 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1123 /* now lift the code to main */
1124 if (IS_AGGREGATE (sym->type)) {
1125 work = initAggregates (sym, sym->ival, NULL);
1127 if (getNelements(sym->type, sym->ival)>1) {
1128 werrorfl (filename, sym->lineDef,
1129 W_EXCESS_INITIALIZERS, "scalar",
1132 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1133 list2expr (sym->ival));
1136 setAstLineno (work, sym->lineDef);
1140 staticAutos = newNode (NULLOP, staticAutos, work);
1147 /* if there is an initial value */
1148 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1150 initList *ilist=sym->ival;
1152 while (ilist->type == INIT_DEEP) {
1153 ilist = ilist->init.deep;
1156 /* update lineno for error msg */
1157 lineno=sym->lineDef;
1158 setAstLineno (ilist->init.node, lineno);
1160 if (IS_AGGREGATE (sym->type)) {
1161 work = initAggregates (sym, sym->ival, NULL);
1163 if (getNelements(sym->type, sym->ival)>1) {
1164 werrorfl (filename, sym->lineDef,
1165 W_EXCESS_INITIALIZERS, "scalar",
1168 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1169 list2expr (sym->ival));
1173 setAstLineno (work, sym->lineDef);
1177 init = newNode (NULLOP, init, work);
1186 /*-----------------------------------------------------------------*/
1187 /* freeStringSymbol - delete a literal string if no more usage */
1188 /*-----------------------------------------------------------------*/
1189 void freeStringSymbol(symbol *sym) {
1190 /* make sure this is a literal string */
1191 assert (sym->isstrlit);
1192 if (--sym->isstrlit == 0) { // lower the usage count
1193 memmap *segment=SPEC_OCLS(sym->etype);
1195 deleteSetItem(&segment->syms, sym);
1200 /*-----------------------------------------------------------------*/
1201 /* stringToSymbol - creates a symbol from a literal string */
1202 /*-----------------------------------------------------------------*/
1204 stringToSymbol (value * val)
1206 char name[SDCC_NAME_MAX + 1];
1207 static int charLbl = 0;
1212 // have we heard this before?
1213 for (sp=statsg->syms; sp; sp=sp->next) {
1215 size = getSize (sym->type);
1216 if (sym->isstrlit && size == getSize (val->type) &&
1217 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1218 // yes, this is old news. Don't publish it again.
1219 sym->isstrlit++; // but raise the usage count
1220 return symbolVal(sym);
1224 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1225 sym = newSymbol (name, 0); /* make it @ level 0 */
1226 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1228 /* copy the type from the value passed */
1229 sym->type = copyLinkChain (val->type);
1230 sym->etype = getSpec (sym->type);
1231 /* change to storage class & output class */
1232 SPEC_SCLS (sym->etype) = S_CODE;
1233 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1234 SPEC_STAT (sym->etype) = 1;
1235 /* make the level & block = 0 */
1236 sym->block = sym->level = 0;
1238 /* create an ival */
1239 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1244 allocVariables (sym);
1247 return symbolVal (sym);
1251 /*-----------------------------------------------------------------*/
1252 /* processBlockVars - will go thru the ast looking for block if */
1253 /* a block is found then will allocate the syms */
1254 /* will also gather the auto inits present */
1255 /*-----------------------------------------------------------------*/
1257 processBlockVars (ast * tree, int *stack, int action)
1262 /* if this is a block */
1263 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1267 if (action == ALLOCATE)
1269 *stack += allocVariables (tree->values.sym);
1270 autoInit = gatherAutoInit (tree->values.sym);
1272 /* if there are auto inits then do them */
1274 tree->left = newNode (NULLOP, autoInit, tree->left);
1276 else /* action is deallocate */
1277 deallocLocal (tree->values.sym);
1280 processBlockVars (tree->left, stack, action);
1281 processBlockVars (tree->right, stack, action);
1286 /*-------------------------------------------------------------*/
1287 /* constExprTree - returns TRUE if this tree is a constant */
1289 /*-------------------------------------------------------------*/
1290 bool constExprTree (ast *cexpr) {
1296 cexpr = decorateType (resolveSymbols (cexpr));
1298 switch (cexpr->type)
1301 if (IS_AST_LIT_VALUE(cexpr)) {
1302 // this is a literal
1305 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1306 // a function's address will never change
1309 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1310 // an array's address will never change
1313 if (IS_AST_SYM_VALUE(cexpr) &&
1314 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1315 // a symbol in code space will never change
1316 // This is only for the 'char *s="hallo"' case and will have to leave
1317 //printf(" code space symbol");
1322 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1323 "unexpected link in expression tree\n");
1326 if (cexpr->opval.op==ARRAYINIT) {
1327 // this is a list of literals
1330 if (cexpr->opval.op=='=') {
1331 return constExprTree(cexpr->right);
1333 if (cexpr->opval.op==CAST) {
1334 // cast ignored, maybe we should throw a warning here?
1335 return constExprTree(cexpr->right);
1337 if (cexpr->opval.op=='&') {
1340 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1343 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1348 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1353 /*-----------------------------------------------------------------*/
1354 /* constExprValue - returns the value of a constant expression */
1355 /* or NULL if it is not a constant expression */
1356 /*-----------------------------------------------------------------*/
1358 constExprValue (ast * cexpr, int check)
1360 cexpr = decorateType (resolveSymbols (cexpr));
1362 /* if this is not a constant then */
1363 if (!IS_LITERAL (cexpr->ftype))
1365 /* then check if this is a literal array
1367 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1368 SPEC_CVAL (cexpr->etype).v_char &&
1369 IS_ARRAY (cexpr->ftype))
1371 value *val = valFromType (cexpr->ftype);
1372 SPEC_SCLS (val->etype) = S_LITERAL;
1373 val->sym = cexpr->opval.val->sym;
1374 val->sym->type = copyLinkChain (cexpr->ftype);
1375 val->sym->etype = getSpec (val->sym->type);
1376 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1380 /* if we are casting a literal value then */
1381 if (IS_AST_OP (cexpr) &&
1382 cexpr->opval.op == CAST &&
1383 IS_LITERAL (cexpr->right->ftype))
1385 return valCastLiteral (cexpr->ftype,
1386 floatFromVal (cexpr->right->opval.val));
1389 if (IS_AST_VALUE (cexpr))
1391 return cexpr->opval.val;
1395 werror (E_CONST_EXPECTED, "found expression");
1400 /* return the value */
1401 return cexpr->opval.val;
1405 /*-----------------------------------------------------------------*/
1406 /* isLabelInAst - will return true if a given label is found */
1407 /*-----------------------------------------------------------------*/
1409 isLabelInAst (symbol * label, ast * tree)
1411 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1414 if (IS_AST_OP (tree) &&
1415 tree->opval.op == LABEL &&
1416 isSymbolEqual (AST_SYMBOL (tree->left), label))
1419 return isLabelInAst (label, tree->right) &&
1420 isLabelInAst (label, tree->left);
1424 /*-----------------------------------------------------------------*/
1425 /* isLoopCountable - return true if the loop count can be determi- */
1426 /* -ned at compile time . */
1427 /*-----------------------------------------------------------------*/
1429 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1430 symbol ** sym, ast ** init, ast ** end)
1433 /* the loop is considered countable if the following
1434 conditions are true :-
1436 a) initExpr :- <sym> = <const>
1437 b) condExpr :- <sym> < <const1>
1438 c) loopExpr :- <sym> ++
1441 /* first check the initExpr */
1442 if (IS_AST_OP (initExpr) &&
1443 initExpr->opval.op == '=' && /* is assignment */
1444 IS_AST_SYM_VALUE (initExpr->left))
1445 { /* left is a symbol */
1447 *sym = AST_SYMBOL (initExpr->left);
1448 *init = initExpr->right;
1453 /* for now the symbol has to be of
1455 if (!IS_INTEGRAL ((*sym)->type))
1458 /* now check condExpr */
1459 if (IS_AST_OP (condExpr))
1462 switch (condExpr->opval.op)
1465 if (IS_AST_SYM_VALUE (condExpr->left) &&
1466 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1467 IS_AST_LIT_VALUE (condExpr->right))
1469 *end = condExpr->right;
1475 if (IS_AST_OP (condExpr->left) &&
1476 condExpr->left->opval.op == '>' &&
1477 IS_AST_LIT_VALUE (condExpr->left->right) &&
1478 IS_AST_SYM_VALUE (condExpr->left->left) &&
1479 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1482 *end = newNode ('+', condExpr->left->right,
1483 newAst_VALUE (constVal ("1")));
1494 /* check loop expression is of the form <sym>++ */
1495 if (!IS_AST_OP (loopExpr))
1498 /* check if <sym> ++ */
1499 if (loopExpr->opval.op == INC_OP)
1505 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1506 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1513 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1514 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1522 if (loopExpr->opval.op == ADD_ASSIGN)
1525 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1526 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1527 IS_AST_LIT_VALUE (loopExpr->right) &&
1528 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1536 /*-----------------------------------------------------------------*/
1537 /* astHasVolatile - returns true if ast contains any volatile */
1538 /*-----------------------------------------------------------------*/
1540 astHasVolatile (ast * tree)
1545 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1548 if (IS_AST_OP (tree))
1549 return astHasVolatile (tree->left) ||
1550 astHasVolatile (tree->right);
1555 /*-----------------------------------------------------------------*/
1556 /* astHasPointer - return true if the ast contains any ptr variable */
1557 /*-----------------------------------------------------------------*/
1559 astHasPointer (ast * tree)
1564 if (IS_AST_LINK (tree))
1567 /* if we hit an array expression then check
1568 only the left side */
1569 if (IS_AST_OP (tree) && tree->opval.op == '[')
1570 return astHasPointer (tree->left);
1572 if (IS_AST_VALUE (tree))
1573 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1575 return astHasPointer (tree->left) ||
1576 astHasPointer (tree->right);
1580 /*-----------------------------------------------------------------*/
1581 /* astHasSymbol - return true if the ast has the given symbol */
1582 /*-----------------------------------------------------------------*/
1584 astHasSymbol (ast * tree, symbol * sym)
1586 if (!tree || IS_AST_LINK (tree))
1589 if (IS_AST_VALUE (tree))
1591 if (IS_AST_SYM_VALUE (tree))
1592 return isSymbolEqual (AST_SYMBOL (tree), sym);
1597 return astHasSymbol (tree->left, sym) ||
1598 astHasSymbol (tree->right, sym);
1601 /*-----------------------------------------------------------------*/
1602 /* astHasDeref - return true if the ast has an indirect access */
1603 /*-----------------------------------------------------------------*/
1605 astHasDeref (ast * tree)
1607 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1610 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1612 return astHasDeref (tree->left) || astHasDeref (tree->right);
1615 /*-----------------------------------------------------------------*/
1616 /* isConformingBody - the loop body has to conform to a set of rules */
1617 /* for the loop to be considered reversible read on for rules */
1618 /*-----------------------------------------------------------------*/
1620 isConformingBody (ast * pbody, symbol * sym, ast * body)
1623 /* we are going to do a pre-order traversal of the
1624 tree && check for the following conditions. (essentially
1625 a set of very shallow tests )
1626 a) the sym passed does not participate in
1627 any arithmetic operation
1628 b) There are no function calls
1629 c) all jumps are within the body
1630 d) address of loop control variable not taken
1631 e) if an assignment has a pointer on the
1632 left hand side make sure right does not have
1633 loop control variable */
1635 /* if we reach the end or a leaf then true */
1636 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1639 /* if anything else is "volatile" */
1640 if (IS_VOLATILE (TETYPE (pbody)))
1643 /* we will walk the body in a pre-order traversal for
1645 switch (pbody->opval.op)
1647 /*------------------------------------------------------------------*/
1649 // if the loopvar is used as an index
1650 if (astHasSymbol(pbody->right, sym)) {
1653 return isConformingBody (pbody->right, sym, body);
1655 /*------------------------------------------------------------------*/
1660 /*------------------------------------------------------------------*/
1664 /* sure we are not sym is not modified */
1666 IS_AST_SYM_VALUE (pbody->left) &&
1667 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1671 IS_AST_SYM_VALUE (pbody->right) &&
1672 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1677 /*------------------------------------------------------------------*/
1679 case '*': /* can be unary : if right is null then unary operation */
1684 /* if right is NULL then unary operation */
1685 /*------------------------------------------------------------------*/
1686 /*----------------------------*/
1688 /*----------------------------*/
1691 if (IS_AST_SYM_VALUE (pbody->left) &&
1692 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1695 return isConformingBody (pbody->left, sym, body);
1699 if (astHasSymbol (pbody->left, sym) ||
1700 astHasSymbol (pbody->right, sym))
1705 /*------------------------------------------------------------------*/
1713 if (IS_AST_SYM_VALUE (pbody->left) &&
1714 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1717 if (IS_AST_SYM_VALUE (pbody->right) &&
1718 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1721 return isConformingBody (pbody->left, sym, body) &&
1722 isConformingBody (pbody->right, sym, body);
1730 if (IS_AST_SYM_VALUE (pbody->left) &&
1731 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1733 return isConformingBody (pbody->left, sym, body);
1735 /*------------------------------------------------------------------*/
1747 case SIZEOF: /* evaluate wihout code generation */
1749 if (IS_AST_SYM_VALUE (pbody->left) &&
1750 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1753 if (IS_AST_SYM_VALUE (pbody->right) &&
1754 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1757 return isConformingBody (pbody->left, sym, body) &&
1758 isConformingBody (pbody->right, sym, body);
1760 /*------------------------------------------------------------------*/
1763 /* if left has a pointer & right has loop
1764 control variable then we cannot */
1765 if (astHasPointer (pbody->left) &&
1766 astHasSymbol (pbody->right, sym))
1768 if (astHasVolatile (pbody->left))
1771 if (IS_AST_SYM_VALUE (pbody->left)) {
1772 // if the loopvar has an assignment
1773 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1775 // if the loopvar is used in another (maybe conditional) block
1776 if (astHasSymbol (pbody->right, sym) &&
1777 (pbody->level >= body->level)) {
1782 if (astHasVolatile (pbody->left))
1785 if (astHasDeref(pbody->right)) return FALSE;
1787 return isConformingBody (pbody->left, sym, body) &&
1788 isConformingBody (pbody->right, sym, body);
1799 assert ("Parser should not have generated this\n");
1801 /*------------------------------------------------------------------*/
1802 /*----------------------------*/
1803 /* comma operator */
1804 /*----------------------------*/
1806 return isConformingBody (pbody->left, sym, body) &&
1807 isConformingBody (pbody->right, sym, body);
1809 /*------------------------------------------------------------------*/
1810 /*----------------------------*/
1812 /*----------------------------*/
1814 /* if local & not passed as paramater then ok */
1815 if (sym->level && !astHasSymbol(pbody->right,sym))
1819 /*------------------------------------------------------------------*/
1820 /*----------------------------*/
1821 /* return statement */
1822 /*----------------------------*/
1827 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1832 if (astHasSymbol (pbody->left, sym))
1839 return isConformingBody (pbody->left, sym, body) &&
1840 isConformingBody (pbody->right, sym, body);
1846 /*-----------------------------------------------------------------*/
1847 /* isLoopReversible - takes a for loop as input && returns true */
1848 /* if the for loop is reversible. If yes will set the value of */
1849 /* the loop control var & init value & termination value */
1850 /*-----------------------------------------------------------------*/
1852 isLoopReversible (ast * loop, symbol ** loopCntrl,
1853 ast ** init, ast ** end)
1855 /* if option says don't do it then don't */
1856 if (optimize.noLoopReverse)
1858 /* there are several tests to determine this */
1860 /* for loop has to be of the form
1861 for ( <sym> = <const1> ;
1862 [<sym> < <const2>] ;
1863 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1865 if (!isLoopCountable (AST_FOR (loop, initExpr),
1866 AST_FOR (loop, condExpr),
1867 AST_FOR (loop, loopExpr),
1868 loopCntrl, init, end))
1871 /* now do some serious checking on the body of the loop
1874 return isConformingBody (loop->left, *loopCntrl, loop->left);
1878 /*-----------------------------------------------------------------*/
1879 /* replLoopSym - replace the loop sym by loop sym -1 */
1880 /*-----------------------------------------------------------------*/
1882 replLoopSym (ast * body, symbol * sym)
1885 if (!body || IS_AST_LINK (body))
1888 if (IS_AST_SYM_VALUE (body))
1891 if (isSymbolEqual (AST_SYMBOL (body), sym))
1895 body->opval.op = '-';
1896 body->left = newAst_VALUE (symbolVal (sym));
1897 body->right = newAst_VALUE (constVal ("1"));
1905 replLoopSym (body->left, sym);
1906 replLoopSym (body->right, sym);
1910 /*-----------------------------------------------------------------*/
1911 /* reverseLoop - do the actual loop reversal */
1912 /*-----------------------------------------------------------------*/
1914 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1918 /* create the following tree
1923 if (sym) goto for_continue ;
1926 /* put it together piece by piece */
1927 rloop = newNode (NULLOP,
1928 createIf (newAst_VALUE (symbolVal (sym)),
1930 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1933 newAst_VALUE (symbolVal (sym)),
1936 replLoopSym (loop->left, sym);
1937 setAstLineno (rloop, init->lineno);
1939 rloop = newNode (NULLOP,
1941 newAst_VALUE (symbolVal (sym)),
1942 newNode ('-', end, init)),
1943 createLabel (AST_FOR (loop, continueLabel),
1947 newNode (SUB_ASSIGN,
1948 newAst_VALUE (symbolVal (sym)),
1949 newAst_VALUE (constVal ("1"))),
1952 rloop->lineno=init->lineno;
1953 return decorateType (rloop);
1957 /*-----------------------------------------------------------------*/
1958 /* searchLitOp - search tree (*ops only) for an ast with literal */
1959 /*-----------------------------------------------------------------*/
1961 searchLitOp (ast *tree, ast **parent, const char *ops)
1965 if (tree && optimize.global_cse)
1967 /* is there a literal operand? */
1969 IS_AST_OP(tree->right) &&
1970 tree->right->right &&
1971 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1973 if (IS_LITERAL (RTYPE (tree->right)) ^
1974 IS_LITERAL (LTYPE (tree->right)))
1976 tree->right->decorated = 0;
1977 tree->decorated = 0;
1981 ret = searchLitOp (tree->right, parent, ops);
1986 IS_AST_OP(tree->left) &&
1987 tree->left->right &&
1988 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1990 if (IS_LITERAL (RTYPE (tree->left)) ^
1991 IS_LITERAL (LTYPE (tree->left)))
1993 tree->left->decorated = 0;
1994 tree->decorated = 0;
1998 ret = searchLitOp (tree->left, parent, ops);
2006 /*-----------------------------------------------------------------*/
2007 /* decorateType - compute type for this tree also does type checking */
2008 /* this is done bottom up, since type have to flow upwards */
2009 /* it also does constant folding, and paramater checking */
2010 /*-----------------------------------------------------------------*/
2012 decorateType (ast * tree)
2020 /* if already has type then do nothing */
2021 if (tree->decorated)
2024 tree->decorated = 1;
2027 /* print the line */
2028 /* if not block & function */
2029 if (tree->type == EX_OP &&
2030 (tree->opval.op != FUNCTION &&
2031 tree->opval.op != BLOCK &&
2032 tree->opval.op != NULLOP))
2034 filename = tree->filename;
2035 lineno = tree->lineno;
2039 /* if any child is an error | this one is an error do nothing */
2040 if (tree->isError ||
2041 (tree->left && tree->left->isError) ||
2042 (tree->right && tree->right->isError))
2045 /*------------------------------------------------------------------*/
2046 /*----------------------------*/
2047 /* leaf has been reached */
2048 /*----------------------------*/
2049 lineno=tree->lineno;
2050 /* if this is of type value */
2051 /* just get the type */
2052 if (tree->type == EX_VALUE)
2055 if (IS_LITERAL (tree->opval.val->etype))
2058 /* if this is a character array then declare it */
2059 if (IS_ARRAY (tree->opval.val->type))
2060 tree->opval.val = stringToSymbol (tree->opval.val);
2062 /* otherwise just copy the type information */
2063 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2067 if (tree->opval.val->sym)
2069 /* if the undefined flag is set then give error message */
2070 if (tree->opval.val->sym->undefined)
2072 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2074 TTYPE (tree) = TETYPE (tree) =
2075 tree->opval.val->type = tree->opval.val->sym->type =
2076 tree->opval.val->etype = tree->opval.val->sym->etype =
2077 copyLinkChain (INTTYPE);
2082 /* if impilicit i.e. struct/union member then no type */
2083 if (tree->opval.val->sym->implicit)
2084 TTYPE (tree) = TETYPE (tree) = NULL;
2089 /* else copy the type */
2090 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2092 /* and mark it as referenced */
2093 tree->opval.val->sym->isref = 1;
2101 /* if type link for the case of cast */
2102 if (tree->type == EX_LINK)
2104 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2112 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2114 if (tree->left && tree->left->type == EX_OPERAND
2115 && (tree->left->opval.op == INC_OP
2116 || tree->left->opval.op == DEC_OP)
2117 && tree->left->left)
2119 tree->left->right = tree->left->left;
2120 tree->left->left = NULL;
2122 if (tree->right && tree->right->type == EX_OPERAND
2123 && (tree->right->opval.op == INC_OP
2124 || tree->right->opval.op == DEC_OP)
2125 && tree->right->left)
2127 tree->right->right = tree->right->left;
2128 tree->right->left = NULL;
2133 dtl = decorateType (tree->left);
2134 /* delay right side for '?' operator since conditional macro expansions might
2136 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2138 /* this is to take care of situations
2139 when the tree gets rewritten */
2140 if (dtl != tree->left)
2142 if (dtr != tree->right)
2144 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2147 if (IS_AST_OP(tree) &&
2148 (tree->opval.op == CAST || tree->opval.op == '=') &&
2149 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2150 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2151 // this is a cast/assign to a bigger type
2152 if (IS_AST_OP(tree->right) &&
2153 IS_INTEGRAL(tree->right->ftype) &&
2154 (tree->right->opval.op == LEFT_OP ||
2155 tree->right->opval.op == '*' ||
2156 tree->right->opval.op == '+' ||
2157 tree->right->opval.op == '-') &&
2158 tree->right->right) {
2159 // we should cast an operand instead of the result
2160 tree->right->decorated = 0;
2161 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2163 tree->right = decorateType(tree->right);
2168 /* depending on type of operator do */
2170 switch (tree->opval.op)
2172 /*------------------------------------------------------------------*/
2173 /*----------------------------*/
2175 /*----------------------------*/
2178 /* determine which is the array & which the index */
2179 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2182 ast *tempTree = tree->left;
2183 tree->left = tree->right;
2184 tree->right = tempTree;
2187 /* first check if this is a array or a pointer */
2188 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2190 werror (E_NEED_ARRAY_PTR, "[]");
2191 goto errorTreeReturn;
2194 /* check if the type of the idx */
2195 if (!IS_INTEGRAL (RTYPE (tree)))
2197 werror (E_IDX_NOT_INT);
2198 goto errorTreeReturn;
2201 /* if the left is an rvalue then error */
2204 werror (E_LVALUE_REQUIRED, "array access");
2205 goto errorTreeReturn;
2208 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2211 /*------------------------------------------------------------------*/
2212 /*----------------------------*/
2214 /*----------------------------*/
2216 /* if this is not a structure */
2217 if (!IS_STRUCT (LTYPE (tree)))
2219 werror (E_STRUCT_UNION, ".");
2220 goto errorTreeReturn;
2222 TTYPE (tree) = structElemType (LTYPE (tree),
2223 (tree->right->type == EX_VALUE ?
2224 tree->right->opval.val : NULL));
2225 TETYPE (tree) = getSpec (TTYPE (tree));
2228 /*------------------------------------------------------------------*/
2229 /*----------------------------*/
2230 /* struct/union pointer */
2231 /*----------------------------*/
2233 /* if not pointer to a structure */
2234 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2236 werror (E_PTR_REQD);
2237 goto errorTreeReturn;
2240 if (!IS_STRUCT (LTYPE (tree)->next))
2242 werror (E_STRUCT_UNION, "->");
2243 goto errorTreeReturn;
2246 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2247 (tree->right->type == EX_VALUE ?
2248 tree->right->opval.val : NULL));
2249 TETYPE (tree) = getSpec (TTYPE (tree));
2251 /* adjust the storage class */
2252 switch (DCL_TYPE(tree->left->ftype)) {
2254 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2257 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2260 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2263 SPEC_SCLS (TETYPE (tree)) = 0;
2266 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2269 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2272 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2275 SPEC_SCLS (TETYPE (tree)) = 0;
2282 /* This breaks with extern declarations, bitfields, and perhaps other */
2283 /* cases (gcse). Let's leave this optimization disabled for now and */
2284 /* ponder if there's a safe way to do this. -- EEP */
2286 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2287 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2289 /* If defined struct type at addr var
2290 then rewrite (&struct var)->member
2292 and define membertype at (addr+offsetof(struct var,member)) temp
2295 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2296 AST_SYMBOL(tree->right));
2298 sym = newSymbol(genSymName (0), 0);
2299 sym->type = TTYPE (tree);
2300 sym->etype = getSpec(sym->type);
2301 sym->lineDef = tree->lineno;
2304 SPEC_STAT (sym->etype) = 1;
2305 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2307 SPEC_ABSA(sym->etype) = 1;
2308 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2311 AST_VALUE (tree) = symbolVal(sym);
2314 tree->type = EX_VALUE;
2322 /*------------------------------------------------------------------*/
2323 /*----------------------------*/
2324 /* ++/-- operation */
2325 /*----------------------------*/
2329 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2330 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2331 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2332 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2341 /*------------------------------------------------------------------*/
2342 /*----------------------------*/
2344 /*----------------------------*/
2345 case '&': /* can be unary */
2346 /* if right is NULL then unary operation */
2347 if (tree->right) /* not an unary operation */
2350 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2352 werror (E_BITWISE_OP);
2353 werror (W_CONTINUE, "left & right types are ");
2354 printTypeChain (LTYPE (tree), stderr);
2355 fprintf (stderr, ",");
2356 printTypeChain (RTYPE (tree), stderr);
2357 fprintf (stderr, "\n");
2358 goto errorTreeReturn;
2361 /* if they are both literal */
2362 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2364 tree->type = EX_VALUE;
2365 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2366 valFromType (RETYPE (tree)), '&');
2368 tree->right = tree->left = NULL;
2369 TETYPE (tree) = tree->opval.val->etype;
2370 TTYPE (tree) = tree->opval.val->type;
2374 /* see if this is a GETHBIT operation if yes
2377 ast *otree = optimizeGetHbit (tree);
2380 return decorateType (otree);
2384 computeType (LTYPE (tree), RTYPE (tree));
2385 TETYPE (tree) = getSpec (TTYPE (tree));
2387 /* if left is a literal exchange left & right */
2388 if (IS_LITERAL (LTYPE (tree)))
2390 ast *tTree = tree->left;
2391 tree->left = tree->right;
2392 tree->right = tTree;
2395 /* if right is a literal and */
2396 /* we can find a 2nd literal in a and-tree then */
2397 /* rearrange the tree */
2398 if (IS_LITERAL (RTYPE (tree)))
2401 ast *litTree = searchLitOp (tree, &parent, "&");
2404 ast *tTree = litTree->left;
2405 litTree->left = tree->right;
2406 tree->right = tTree;
2407 /* both operands in tTree are literal now */
2408 decorateType (parent);
2412 LRVAL (tree) = RRVAL (tree) = 1;
2416 /*------------------------------------------------------------------*/
2417 /*----------------------------*/
2419 /*----------------------------*/
2420 p = newLink (DECLARATOR);
2421 /* if bit field then error */
2422 if (IS_BITVAR (tree->left->etype))
2424 werror (E_ILLEGAL_ADDR, "address of bit variable");
2425 goto errorTreeReturn;
2428 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2430 werror (E_ILLEGAL_ADDR, "address of register variable");
2431 goto errorTreeReturn;
2434 if (IS_FUNC (LTYPE (tree)))
2436 // this ought to be ignored
2437 return (tree->left);
2440 if (IS_LITERAL(LTYPE(tree)))
2442 werror (E_ILLEGAL_ADDR, "address of literal");
2443 goto errorTreeReturn;
2448 werror (E_LVALUE_REQUIRED, "address of");
2449 goto errorTreeReturn;
2452 DCL_TYPE (p) = POINTER;
2453 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2454 DCL_TYPE (p) = CPOINTER;
2455 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2456 DCL_TYPE (p) = FPOINTER;
2457 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2458 DCL_TYPE (p) = PPOINTER;
2459 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2460 DCL_TYPE (p) = IPOINTER;
2461 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2462 DCL_TYPE (p) = EEPPOINTER;
2463 else if (SPEC_OCLS(tree->left->etype))
2464 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2466 DCL_TYPE (p) = POINTER;
2468 if (IS_AST_SYM_VALUE (tree->left))
2470 AST_SYMBOL (tree->left)->addrtaken = 1;
2471 AST_SYMBOL (tree->left)->allocreq = 1;
2474 p->next = LTYPE (tree);
2476 TETYPE (tree) = getSpec (TTYPE (tree));
2481 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2482 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2484 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2485 AST_SYMBOL(tree->left->right));
2486 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2487 valueFromLit(element->offset));
2490 tree->type = EX_VALUE;
2491 tree->values.literalFromCast = 1;
2497 /*------------------------------------------------------------------*/
2498 /*----------------------------*/
2500 /*----------------------------*/
2502 /* if the rewrite succeeds then don't go any furthur */
2504 ast *wtree = optimizeRRCRLC (tree);
2506 return decorateType (wtree);
2508 wtree = optimizeSWAP (tree);
2510 return decorateType (wtree);
2515 /* if left is a literal exchange left & right */
2516 if (IS_LITERAL (LTYPE (tree)))
2518 ast *tTree = tree->left;
2519 tree->left = tree->right;
2520 tree->right = tTree;
2523 /* if right is a literal and */
2524 /* we can find a 2nd literal in a or-tree then */
2525 /* rearrange the tree */
2526 if (IS_LITERAL (RTYPE (tree)))
2529 ast *litTree = searchLitOp (tree, &parent, "|");
2532 ast *tTree = litTree->left;
2533 litTree->left = tree->right;
2534 tree->right = tTree;
2535 /* both operands in tTree are literal now */
2536 decorateType (parent);
2539 /*------------------------------------------------------------------*/
2540 /*----------------------------*/
2542 /*----------------------------*/
2544 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2546 werror (E_BITWISE_OP);
2547 werror (W_CONTINUE, "left & right types are ");
2548 printTypeChain (LTYPE (tree), stderr);
2549 fprintf (stderr, ",");
2550 printTypeChain (RTYPE (tree), stderr);
2551 fprintf (stderr, "\n");
2552 goto errorTreeReturn;
2555 /* if they are both literal then */
2556 /* rewrite the tree */
2557 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2559 tree->type = EX_VALUE;
2560 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2561 valFromType (RETYPE (tree)),
2563 tree->right = tree->left = NULL;
2564 TETYPE (tree) = tree->opval.val->etype;
2565 TTYPE (tree) = tree->opval.val->type;
2569 /* if left is a literal exchange left & right */
2570 if (IS_LITERAL (LTYPE (tree)))
2572 ast *tTree = tree->left;
2573 tree->left = tree->right;
2574 tree->right = tTree;
2577 /* if right is a literal and */
2578 /* we can find a 2nd literal in a xor-tree then */
2579 /* rearrange the tree */
2580 if (IS_LITERAL (RTYPE (tree)))
2583 ast *litTree = searchLitOp (tree, &parent, "^");
2586 ast *tTree = litTree->left;
2587 litTree->left = tree->right;
2588 tree->right = tTree;
2589 /* both operands in litTree are literal now */
2590 decorateType (parent);
2594 LRVAL (tree) = RRVAL (tree) = 1;
2595 TETYPE (tree) = getSpec (TTYPE (tree) =
2596 computeType (LTYPE (tree),
2599 /*------------------------------------------------------------------*/
2600 /*----------------------------*/
2602 /*----------------------------*/
2604 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2606 werror (E_INVALID_OP, "divide");
2607 goto errorTreeReturn;
2609 /* if they are both literal then */
2610 /* rewrite the tree */
2611 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2613 tree->type = EX_VALUE;
2614 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2615 valFromType (RETYPE (tree)));
2616 tree->right = tree->left = NULL;
2617 TETYPE (tree) = getSpec (TTYPE (tree) =
2618 tree->opval.val->type);
2622 LRVAL (tree) = RRVAL (tree) = 1;
2623 TETYPE (tree) = getSpec (TTYPE (tree) =
2624 computeType (LTYPE (tree),
2627 /* if right is a literal and */
2628 /* left is also a division by a literal then */
2629 /* rearrange the tree */
2630 if (IS_LITERAL (RTYPE (tree))
2631 /* avoid infinite loop */
2632 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2635 ast *litTree = searchLitOp (tree, &parent, "/");
2638 if (IS_LITERAL (RTYPE (litTree)))
2641 litTree->right = newNode ('*', litTree->right, tree->right);
2642 litTree->right->lineno = tree->lineno;
2644 tree->right->opval.val = constVal ("1");
2645 decorateType (parent);
2649 /* litTree->left is literal: no gcse possible.
2650 We can't call decorateType(parent), because
2651 this would cause an infinit loop. */
2652 parent->decorated = 1;
2653 decorateType (litTree);
2660 /*------------------------------------------------------------------*/
2661 /*----------------------------*/
2663 /*----------------------------*/
2665 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2667 werror (E_BITWISE_OP);
2668 werror (W_CONTINUE, "left & right types are ");
2669 printTypeChain (LTYPE (tree), stderr);
2670 fprintf (stderr, ",");
2671 printTypeChain (RTYPE (tree), stderr);
2672 fprintf (stderr, "\n");
2673 goto errorTreeReturn;
2675 /* if they are both literal then */
2676 /* rewrite the tree */
2677 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2679 tree->type = EX_VALUE;
2680 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2681 valFromType (RETYPE (tree)));
2682 tree->right = tree->left = NULL;
2683 TETYPE (tree) = getSpec (TTYPE (tree) =
2684 tree->opval.val->type);
2687 LRVAL (tree) = RRVAL (tree) = 1;
2688 TETYPE (tree) = getSpec (TTYPE (tree) =
2689 computeType (LTYPE (tree),
2693 /*------------------------------------------------------------------*/
2694 /*----------------------------*/
2695 /* address dereference */
2696 /*----------------------------*/
2697 case '*': /* can be unary : if right is null then unary operation */
2700 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2702 werror (E_PTR_REQD);
2703 goto errorTreeReturn;
2708 werror (E_LVALUE_REQUIRED, "pointer deref");
2709 goto errorTreeReturn;
2711 if (IS_ADDRESS_OF_OP(tree->left))
2713 /* replace *&obj with obj */
2714 return tree->left->left;
2716 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2717 TETYPE (tree) = getSpec (TTYPE (tree));
2718 /* adjust the storage class */
2719 switch (DCL_TYPE(tree->left->ftype)) {
2721 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2724 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2727 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2730 SPEC_SCLS (TETYPE (tree)) = 0;
2733 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2736 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2739 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2742 SPEC_SCLS (TETYPE (tree)) = 0;
2751 /*------------------------------------------------------------------*/
2752 /*----------------------------*/
2753 /* multiplication */
2754 /*----------------------------*/
2755 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2757 werror (E_INVALID_OP, "multiplication");
2758 goto errorTreeReturn;
2761 /* if they are both literal then */
2762 /* rewrite the tree */
2763 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2765 tree->type = EX_VALUE;
2766 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2767 valFromType (RETYPE (tree)));
2768 tree->right = tree->left = NULL;
2769 TETYPE (tree) = getSpec (TTYPE (tree) =
2770 tree->opval.val->type);
2774 /* if left is a literal exchange left & right */
2775 if (IS_LITERAL (LTYPE (tree)))
2777 ast *tTree = tree->left;
2778 tree->left = tree->right;
2779 tree->right = tTree;
2782 /* if right is a literal and */
2783 /* we can find a 2nd literal in a mul-tree then */
2784 /* rearrange the tree */
2785 if (IS_LITERAL (RTYPE (tree)))
2788 ast *litTree = searchLitOp (tree, &parent, "*");
2791 ast *tTree = litTree->left;
2792 litTree->left = tree->right;
2793 tree->right = tTree;
2794 /* both operands in litTree are literal now */
2795 decorateType (parent);
2799 LRVAL (tree) = RRVAL (tree) = 1;
2800 TETYPE (tree) = getSpec (TTYPE (tree) =
2801 computeType (LTYPE (tree),
2804 /* promote result to int if left & right are char
2805 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2806 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2807 SPEC_NOUN(TETYPE(tree)) = V_INT;
2812 /*------------------------------------------------------------------*/
2813 /*----------------------------*/
2814 /* unary '+' operator */
2815 /*----------------------------*/
2820 if (!IS_ARITHMETIC (LTYPE (tree)))
2822 werror (E_UNARY_OP, '+');
2823 goto errorTreeReturn;
2826 /* if left is a literal then do it */
2827 if (IS_LITERAL (LTYPE (tree)))
2829 tree->type = EX_VALUE;
2830 tree->opval.val = valFromType (LETYPE (tree));
2832 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2836 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2840 /*------------------------------------------------------------------*/
2841 /*----------------------------*/
2843 /*----------------------------*/
2845 /* this is not a unary operation */
2846 /* if both pointers then problem */
2847 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2848 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2850 werror (E_PTR_PLUS_PTR);
2851 goto errorTreeReturn;
2854 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2855 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2857 werror (E_PLUS_INVALID, "+");
2858 goto errorTreeReturn;
2861 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2862 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2864 werror (E_PLUS_INVALID, "+");
2865 goto errorTreeReturn;
2867 /* if they are both literal then */
2868 /* rewrite the tree */
2869 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2871 tree->type = EX_VALUE;
2872 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2873 valFromType (RETYPE (tree)));
2874 tree->right = tree->left = NULL;
2875 TETYPE (tree) = getSpec (TTYPE (tree) =
2876 tree->opval.val->type);
2880 /* if the right is a pointer or left is a literal
2881 xchange left & right */
2882 if (IS_ARRAY (RTYPE (tree)) ||
2883 IS_PTR (RTYPE (tree)) ||
2884 IS_LITERAL (LTYPE (tree)))
2886 ast *tTree = tree->left;
2887 tree->left = tree->right;
2888 tree->right = tTree;
2891 /* if right is a literal and */
2892 /* left is also an addition/subtraction with a literal then */
2893 /* rearrange the tree */
2894 if (IS_LITERAL (RTYPE (tree)))
2896 ast *litTree, *parent;
2897 litTree = searchLitOp (tree, &parent, "+-");
2900 if (litTree->opval.op == '+')
2903 ast *tTree = litTree->left;
2904 litTree->left = tree->right;
2905 tree->right = tree->left;
2908 else if (litTree->opval.op == '-')
2910 if (IS_LITERAL (RTYPE (litTree)))
2913 ast *tTree = litTree->left;
2914 litTree->left = tree->right;
2915 tree->right = tTree;
2920 ast *tTree = litTree->right;
2921 litTree->right = tree->right;
2922 tree->right = tTree;
2923 litTree->opval.op = '+';
2924 tree->opval.op = '-';
2927 decorateType (parent);
2931 LRVAL (tree) = RRVAL (tree) = 1;
2932 /* if the left is a pointer */
2933 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2934 TETYPE (tree) = getSpec (TTYPE (tree) =
2937 TETYPE (tree) = getSpec (TTYPE (tree) =
2938 computeType (LTYPE (tree),
2942 /*------------------------------------------------------------------*/
2943 /*----------------------------*/
2945 /*----------------------------*/
2946 case '-': /* can be unary */
2947 /* if right is null then unary */
2951 if (!IS_ARITHMETIC (LTYPE (tree)))
2953 werror (E_UNARY_OP, tree->opval.op);
2954 goto errorTreeReturn;
2957 /* if left is a literal then do it */
2958 if (IS_LITERAL (LTYPE (tree)))
2960 tree->type = EX_VALUE;
2961 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2963 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2964 SPEC_USIGN(TETYPE(tree)) = 0;
2968 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2972 /*------------------------------------------------------------------*/
2973 /*----------------------------*/
2975 /*----------------------------*/
2977 if (!(IS_PTR (LTYPE (tree)) ||
2978 IS_ARRAY (LTYPE (tree)) ||
2979 IS_ARITHMETIC (LTYPE (tree))))
2981 werror (E_PLUS_INVALID, "-");
2982 goto errorTreeReturn;
2985 if (!(IS_PTR (RTYPE (tree)) ||
2986 IS_ARRAY (RTYPE (tree)) ||
2987 IS_ARITHMETIC (RTYPE (tree))))
2989 werror (E_PLUS_INVALID, "-");
2990 goto errorTreeReturn;
2993 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2994 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2995 IS_INTEGRAL (RTYPE (tree))))
2997 werror (E_PLUS_INVALID, "-");
2998 goto errorTreeReturn;
3001 /* if they are both literal then */
3002 /* rewrite the tree */
3003 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3005 tree->type = EX_VALUE;
3006 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3007 valFromType (RETYPE (tree)));
3008 tree->right = tree->left = NULL;
3009 TETYPE (tree) = getSpec (TTYPE (tree) =
3010 tree->opval.val->type);
3014 /* if the left & right are equal then zero */
3015 if (isAstEqual (tree->left, tree->right))
3017 tree->type = EX_VALUE;
3018 tree->left = tree->right = NULL;
3019 tree->opval.val = constVal ("0");
3020 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3024 /* if both of them are pointers or arrays then */
3025 /* the result is going to be an integer */
3026 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3027 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3028 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3030 /* if only the left is a pointer */
3031 /* then result is a pointer */
3032 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3033 TETYPE (tree) = getSpec (TTYPE (tree) =
3036 TETYPE (tree) = getSpec (TTYPE (tree) =
3037 computeType (LTYPE (tree),
3040 LRVAL (tree) = RRVAL (tree) = 1;
3042 /* if right is a literal and */
3043 /* left is also an addition/subtraction with a literal then */
3044 /* rearrange the tree */
3045 if (IS_LITERAL (RTYPE (tree))
3046 /* avoid infinite loop */
3047 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3049 ast *litTree, *litParent;
3050 litTree = searchLitOp (tree, &litParent, "+-");
3053 if (litTree->opval.op == '+')
3056 litTree->right = newNode ('-', litTree->right, tree->right);
3057 litTree->right->lineno = tree->lineno;
3059 tree->right->opval.val = constVal ("0");
3061 else if (litTree->opval.op == '-')
3063 if (IS_LITERAL (RTYPE (litTree)))
3066 litTree->right = newNode ('+', tree->right, litTree->right);
3067 litTree->right->lineno = tree->lineno;
3069 tree->right->opval.val = constVal ("0");
3074 ast *tTree = litTree->right;
3075 litTree->right = tree->right;
3076 tree->right = tTree;
3079 decorateType (litParent);
3084 /*------------------------------------------------------------------*/
3085 /*----------------------------*/
3087 /*----------------------------*/
3089 /* can be only integral type */
3090 if (!IS_INTEGRAL (LTYPE (tree)))
3092 werror (E_UNARY_OP, tree->opval.op);
3093 goto errorTreeReturn;
3096 /* if left is a literal then do it */
3097 if (IS_LITERAL (LTYPE (tree)))
3099 tree->type = EX_VALUE;
3100 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3102 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3106 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3109 /*------------------------------------------------------------------*/
3110 /*----------------------------*/
3112 /*----------------------------*/
3114 /* can be pointer */
3115 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3116 !IS_PTR (LTYPE (tree)) &&
3117 !IS_ARRAY (LTYPE (tree)))
3119 werror (E_UNARY_OP, tree->opval.op);
3120 goto errorTreeReturn;
3123 /* if left is a literal then do it */
3124 if (IS_LITERAL (LTYPE (tree)))
3126 tree->type = EX_VALUE;
3127 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3129 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3133 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3136 /*------------------------------------------------------------------*/
3137 /*----------------------------*/
3139 /*----------------------------*/
3143 TTYPE (tree) = LTYPE (tree);
3144 TETYPE (tree) = LETYPE (tree);
3148 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3153 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3155 werror (E_SHIFT_OP_INVALID);
3156 werror (W_CONTINUE, "left & right types are ");
3157 printTypeChain (LTYPE (tree), stderr);
3158 fprintf (stderr, ",");
3159 printTypeChain (RTYPE (tree), stderr);
3160 fprintf (stderr, "\n");
3161 goto errorTreeReturn;
3164 /* if they are both literal then */
3165 /* rewrite the tree */
3166 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3168 tree->type = EX_VALUE;
3169 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3170 valFromType (RETYPE (tree)),
3171 (tree->opval.op == LEFT_OP ? 1 : 0));
3172 tree->right = tree->left = NULL;
3173 TETYPE (tree) = getSpec (TTYPE (tree) =
3174 tree->opval.val->type);
3178 /* if only the right side is a literal & we are
3179 shifting more than size of the left operand then zero */
3180 if (IS_LITERAL (RTYPE (tree)) &&
3181 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3182 (getSize (LTYPE (tree)) * 8))
3184 if (tree->opval.op==LEFT_OP ||
3185 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3186 lineno=tree->lineno;
3187 werror (W_SHIFT_CHANGED,
3188 (tree->opval.op == LEFT_OP ? "left" : "right"));
3189 tree->type = EX_VALUE;
3190 tree->left = tree->right = NULL;
3191 tree->opval.val = constVal ("0");
3192 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3196 LRVAL (tree) = RRVAL (tree) = 1;
3197 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3198 if (IS_LITERAL (TTYPE (tree)))
3199 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3202 /*------------------------------------------------------------------*/
3203 /*----------------------------*/
3205 /*----------------------------*/
3206 case CAST: /* change the type */
3207 /* cannot cast to an aggregate type */
3208 if (IS_AGGREGATE (LTYPE (tree)))
3210 werror (E_CAST_ILLEGAL);
3211 goto errorTreeReturn;
3214 /* make sure the type is complete and sane */
3215 checkTypeSanity(LETYPE(tree), "(cast)");
3218 /* if the right is a literal replace the tree */
3219 if (IS_LITERAL (RETYPE (tree))) {
3220 if (!IS_PTR (LTYPE (tree))) {
3221 tree->type = EX_VALUE;
3223 valCastLiteral (LTYPE (tree),
3224 floatFromVal (valFromType (RETYPE (tree))));
3227 TTYPE (tree) = tree->opval.val->type;
3228 tree->values.literalFromCast = 1;
3229 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3230 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3231 sym_link *rest = LTYPE(tree)->next;
3232 werror(W_LITERAL_GENERIC);
3233 TTYPE(tree) = newLink(DECLARATOR);
3234 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3235 TTYPE(tree)->next = rest;
3236 tree->left->opval.lnk = TTYPE(tree);
3239 TTYPE (tree) = LTYPE (tree);
3243 TTYPE (tree) = LTYPE (tree);
3247 #if 0 // this is already checked, now this could be explicit
3248 /* if pointer to struct then check names */
3249 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3250 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3251 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3253 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3254 SPEC_STRUCT(LETYPE(tree))->tag);
3257 if (IS_ADDRESS_OF_OP(tree->right)
3258 && IS_AST_SYM_VALUE (tree->right->left)
3259 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3261 tree->type = EX_VALUE;
3263 valCastLiteral (LTYPE (tree),
3264 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3265 TTYPE (tree) = tree->opval.val->type;
3266 TETYPE (tree) = getSpec (TTYPE (tree));
3269 tree->values.literalFromCast = 1;
3273 /* handle offsetof macro: */
3274 /* #define offsetof(TYPE, MEMBER) \ */
3275 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3276 if (IS_ADDRESS_OF_OP(tree->right)
3277 && IS_AST_OP (tree->right->left)
3278 && tree->right->left->opval.op == PTR_OP
3279 && IS_AST_OP (tree->right->left->left)
3280 && tree->right->left->left->opval.op == CAST
3281 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3283 symbol *element = getStructElement (
3284 SPEC_STRUCT (LETYPE(tree->right->left)),
3285 AST_SYMBOL(tree->right->left->right)
3289 tree->type = EX_VALUE;
3290 tree->opval.val = valCastLiteral (
3293 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3296 TTYPE (tree) = tree->opval.val->type;
3297 TETYPE (tree) = getSpec (TTYPE (tree));
3304 /* if the right is a literal replace the tree */
3305 if (IS_LITERAL (RETYPE (tree))) {
3306 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3307 /* rewrite (type *)litaddr
3309 and define type at litaddr temp
3310 (but only if type's storage class is not generic)
3312 ast *newTree = newNode ('&', NULL, NULL);
3315 TTYPE (newTree) = LTYPE (tree);
3316 TETYPE (newTree) = getSpec(LTYPE (tree));
3318 /* define a global symbol at the casted address*/
3319 sym = newSymbol(genSymName (0), 0);
3320 sym->type = LTYPE (tree)->next;
3322 sym->type = newLink (V_VOID);
3323 sym->etype = getSpec(sym->type);
3324 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3325 sym->lineDef = tree->lineno;
3328 SPEC_STAT (sym->etype) = 1;
3329 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3330 SPEC_ABSA(sym->etype) = 1;
3331 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3334 newTree->left = newAst_VALUE(symbolVal(sym));
3335 newTree->left->lineno = tree->lineno;
3336 LTYPE (newTree) = sym->type;
3337 LETYPE (newTree) = sym->etype;
3338 LLVAL (newTree) = 1;
3339 LRVAL (newTree) = 0;
3340 TLVAL (newTree) = 1;
3343 if (!IS_PTR (LTYPE (tree))) {
3344 tree->type = EX_VALUE;
3346 valCastLiteral (LTYPE (tree),
3347 floatFromVal (valFromType (RTYPE (tree))));
3348 TTYPE (tree) = tree->opval.val->type;
3351 tree->values.literalFromCast = 1;
3352 TETYPE (tree) = getSpec (TTYPE (tree));
3356 TTYPE (tree) = LTYPE (tree);
3360 TETYPE (tree) = getSpec (TTYPE (tree));
3364 /*------------------------------------------------------------------*/
3365 /*----------------------------*/
3366 /* logical &&, || */
3367 /*----------------------------*/
3370 /* each must me arithmetic type or be a pointer */
3371 if (!IS_PTR (LTYPE (tree)) &&
3372 !IS_ARRAY (LTYPE (tree)) &&
3373 !IS_INTEGRAL (LTYPE (tree)))
3375 werror (E_COMPARE_OP);
3376 goto errorTreeReturn;
3379 if (!IS_PTR (RTYPE (tree)) &&
3380 !IS_ARRAY (RTYPE (tree)) &&
3381 !IS_INTEGRAL (RTYPE (tree)))
3383 werror (E_COMPARE_OP);
3384 goto errorTreeReturn;
3386 /* if they are both literal then */
3387 /* rewrite the tree */
3388 if (IS_LITERAL (RTYPE (tree)) &&
3389 IS_LITERAL (LTYPE (tree)))
3391 tree->type = EX_VALUE;
3392 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3393 valFromType (RTYPE (tree)),
3395 tree->right = tree->left = NULL;
3396 TETYPE (tree) = getSpec (TTYPE (tree) =
3397 tree->opval.val->type);
3400 LRVAL (tree) = RRVAL (tree) = 1;
3401 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3404 /*------------------------------------------------------------------*/
3405 /*----------------------------*/
3406 /* comparison operators */
3407 /*----------------------------*/
3415 ast *lt = optimizeCompare (tree);
3421 /* if they are pointers they must be castable */
3422 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3424 if (tree->opval.op==EQ_OP &&
3425 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3426 // we cannot cast a gptr to a !gptr: switch the leaves
3427 struct ast *s=tree->left;
3428 tree->left=tree->right;
3431 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3433 werror (E_COMPARE_OP);
3434 fprintf (stderr, "comparing type ");
3435 printTypeChain (LTYPE (tree), stderr);
3436 fprintf (stderr, "to type ");
3437 printTypeChain (RTYPE (tree), stderr);
3438 fprintf (stderr, "\n");
3439 goto errorTreeReturn;
3442 /* else they should be promotable to one another */
3445 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3446 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3448 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3450 werror (E_COMPARE_OP);
3451 fprintf (stderr, "comparing type ");
3452 printTypeChain (LTYPE (tree), stderr);
3453 fprintf (stderr, "to type ");
3454 printTypeChain (RTYPE (tree), stderr);
3455 fprintf (stderr, "\n");
3456 goto errorTreeReturn;
3459 /* if unsigned value < 0 then always false */
3460 /* if (unsigned value) > 0 then (unsigned value) */
3461 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3462 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3464 if (tree->opval.op == '<') {
3467 if (tree->opval.op == '>') {
3471 /* if they are both literal then */
3472 /* rewrite the tree */
3473 if (IS_LITERAL (RTYPE (tree)) &&
3474 IS_LITERAL (LTYPE (tree)))
3476 tree->type = EX_VALUE;
3477 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3478 valFromType (RETYPE (tree)),
3480 tree->right = tree->left = NULL;
3481 TETYPE (tree) = getSpec (TTYPE (tree) =
3482 tree->opval.val->type);
3485 LRVAL (tree) = RRVAL (tree) = 1;
3486 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3489 /*------------------------------------------------------------------*/
3490 /*----------------------------*/
3492 /*----------------------------*/
3493 case SIZEOF: /* evaluate wihout code generation */
3494 /* change the type to a integer */
3495 tree->type = EX_VALUE;
3496 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3497 tree->opval.val = constVal (buffer);
3498 tree->right = tree->left = NULL;
3499 TETYPE (tree) = getSpec (TTYPE (tree) =
3500 tree->opval.val->type);
3503 /*------------------------------------------------------------------*/
3504 /*----------------------------*/
3506 /*----------------------------*/
3508 /* return typeof enum value */
3509 tree->type = EX_VALUE;
3512 if (IS_SPEC(tree->right->ftype)) {
3513 switch (SPEC_NOUN(tree->right->ftype)) {
3515 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3516 else typeofv = TYPEOF_INT;
3519 typeofv = TYPEOF_FLOAT;
3522 typeofv = TYPEOF_CHAR;
3525 typeofv = TYPEOF_VOID;
3528 typeofv = TYPEOF_STRUCT;
3531 typeofv = TYPEOF_BITFIELD;
3534 typeofv = TYPEOF_BIT;
3537 typeofv = TYPEOF_SBIT;
3543 switch (DCL_TYPE(tree->right->ftype)) {
3545 typeofv = TYPEOF_POINTER;
3548 typeofv = TYPEOF_FPOINTER;
3551 typeofv = TYPEOF_CPOINTER;
3554 typeofv = TYPEOF_GPOINTER;
3557 typeofv = TYPEOF_PPOINTER;
3560 typeofv = TYPEOF_IPOINTER;
3563 typeofv = TYPEOF_ARRAY;
3566 typeofv = TYPEOF_FUNCTION;
3572 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3573 tree->opval.val = constVal (buffer);
3574 tree->right = tree->left = NULL;
3575 TETYPE (tree) = getSpec (TTYPE (tree) =
3576 tree->opval.val->type);
3579 /*------------------------------------------------------------------*/
3580 /*----------------------------*/
3581 /* conditional operator '?' */
3582 /*----------------------------*/
3584 /* the type is value of the colon operator (on the right) */
3585 assert(IS_COLON_OP(tree->right));
3586 /* if already known then replace the tree : optimizer will do it
3587 but faster to do it here */
3588 if (IS_LITERAL (LTYPE(tree))) {
3589 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3590 return decorateType(tree->right->left) ;
3592 return decorateType(tree->right->right) ;
3595 tree->right = decorateType(tree->right);
3596 TTYPE (tree) = RTYPE(tree);
3597 TETYPE (tree) = getSpec (TTYPE (tree));
3602 /* if they don't match we have a problem */
3603 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3605 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3606 goto errorTreeReturn;
3609 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3610 TETYPE (tree) = getSpec (TTYPE (tree));
3614 #if 0 // assignment operators are converted by the parser
3615 /*------------------------------------------------------------------*/
3616 /*----------------------------*/
3617 /* assignment operators */
3618 /*----------------------------*/
3621 /* for these it must be both must be integral */
3622 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3623 !IS_ARITHMETIC (RTYPE (tree)))
3625 werror (E_OPS_INTEGRAL);
3626 goto errorTreeReturn;
3629 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3631 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3632 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3636 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3637 goto errorTreeReturn;
3648 /* for these it must be both must be integral */
3649 if (!IS_INTEGRAL (LTYPE (tree)) ||
3650 !IS_INTEGRAL (RTYPE (tree)))
3652 werror (E_OPS_INTEGRAL);
3653 goto errorTreeReturn;
3656 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3658 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3659 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3663 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3664 goto errorTreeReturn;
3670 /*------------------------------------------------------------------*/
3671 /*----------------------------*/
3673 /*----------------------------*/
3675 if (!(IS_PTR (LTYPE (tree)) ||
3676 IS_ARITHMETIC (LTYPE (tree))))
3678 werror (E_PLUS_INVALID, "-=");
3679 goto errorTreeReturn;
3682 if (!(IS_PTR (RTYPE (tree)) ||
3683 IS_ARITHMETIC (RTYPE (tree))))
3685 werror (E_PLUS_INVALID, "-=");
3686 goto errorTreeReturn;
3689 TETYPE (tree) = getSpec (TTYPE (tree) =
3690 computeType (LTYPE (tree),
3693 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3694 werror (E_CODE_WRITE, "-=");
3698 werror (E_LVALUE_REQUIRED, "-=");
3699 goto errorTreeReturn;
3705 /*------------------------------------------------------------------*/
3706 /*----------------------------*/
3708 /*----------------------------*/
3710 /* this is not a unary operation */
3711 /* if both pointers then problem */
3712 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3714 werror (E_PTR_PLUS_PTR);
3715 goto errorTreeReturn;
3718 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3720 werror (E_PLUS_INVALID, "+=");
3721 goto errorTreeReturn;
3724 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3726 werror (E_PLUS_INVALID, "+=");
3727 goto errorTreeReturn;
3730 TETYPE (tree) = getSpec (TTYPE (tree) =
3731 computeType (LTYPE (tree),
3734 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3735 werror (E_CODE_WRITE, "+=");
3739 werror (E_LVALUE_REQUIRED, "+=");
3740 goto errorTreeReturn;
3743 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3744 tree->opval.op = '=';
3749 /*------------------------------------------------------------------*/
3750 /*----------------------------*/
3751 /* straight assignemnt */
3752 /*----------------------------*/
3754 /* cannot be an aggregate */
3755 if (IS_AGGREGATE (LTYPE (tree)))
3757 werror (E_AGGR_ASSIGN);
3758 goto errorTreeReturn;
3761 /* they should either match or be castable */
3762 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3764 werror (E_TYPE_MISMATCH, "assignment", " ");
3765 printFromToType(RTYPE(tree),LTYPE(tree));
3768 /* if the left side of the tree is of type void
3769 then report error */
3770 if (IS_VOID (LTYPE (tree)))
3772 werror (E_CAST_ZERO);
3773 printFromToType(RTYPE(tree), LTYPE(tree));
3776 TETYPE (tree) = getSpec (TTYPE (tree) =
3780 if (!tree->initMode ) {
3781 if (IS_CONSTANT(LTYPE(tree)))
3782 werror (E_CODE_WRITE, "=");
3786 werror (E_LVALUE_REQUIRED, "=");
3787 goto errorTreeReturn;
3792 /*------------------------------------------------------------------*/
3793 /*----------------------------*/
3794 /* comma operator */
3795 /*----------------------------*/
3797 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3800 /*------------------------------------------------------------------*/
3801 /*----------------------------*/
3803 /*----------------------------*/
3807 if (processParms (tree->left,
3808 FUNC_ARGS(tree->left->ftype),
3809 tree->right, &parmNumber, TRUE)) {
3810 goto errorTreeReturn;
3813 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3814 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3816 reverseParms (tree->right);
3819 if (IS_CODEPTR(LTYPE(tree))) {
3820 TTYPE(tree) = LTYPE(tree)->next->next;
3822 TTYPE(tree) = LTYPE(tree)->next;
3824 TETYPE (tree) = getSpec (TTYPE (tree));
3827 /*------------------------------------------------------------------*/
3828 /*----------------------------*/
3829 /* return statement */
3830 /*----------------------------*/
3835 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3837 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
3838 printFromToType (RTYPE(tree), currFunc->type->next);
3839 goto errorTreeReturn;
3842 if (IS_VOID (currFunc->type->next)
3844 !IS_VOID (RTYPE (tree)))
3846 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
3847 goto errorTreeReturn;
3850 /* if there is going to be a casing required then add it */
3851 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3854 decorateType (newNode (CAST,
3855 newAst_LINK (copyLinkChain (currFunc->type->next)),
3864 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3866 werror (W_VOID_FUNC, currFunc->name);
3867 goto errorTreeReturn;
3870 TTYPE (tree) = TETYPE (tree) = NULL;
3873 /*------------------------------------------------------------------*/
3874 /*----------------------------*/
3875 /* switch statement */
3876 /*----------------------------*/
3878 /* the switch value must be an integer */
3879 if (!IS_INTEGRAL (LTYPE (tree)))
3881 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
3882 goto errorTreeReturn;
3885 TTYPE (tree) = TETYPE (tree) = NULL;
3888 /*------------------------------------------------------------------*/
3889 /*----------------------------*/
3891 /*----------------------------*/
3893 tree->left = backPatchLabels (tree->left,
3896 TTYPE (tree) = TETYPE (tree) = NULL;
3899 /*------------------------------------------------------------------*/
3900 /*----------------------------*/
3902 /*----------------------------*/
3905 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3906 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3907 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3909 /* if the for loop is reversible then
3910 reverse it otherwise do what we normally
3916 if (isLoopReversible (tree, &sym, &init, &end))
3917 return reverseLoop (tree, sym, init, end);
3919 return decorateType (createFor (AST_FOR (tree, trueLabel),
3920 AST_FOR (tree, continueLabel),
3921 AST_FOR (tree, falseLabel),
3922 AST_FOR (tree, condLabel),
3923 AST_FOR (tree, initExpr),
3924 AST_FOR (tree, condExpr),
3925 AST_FOR (tree, loopExpr),
3929 TTYPE (tree) = TETYPE (tree) = NULL;
3933 /* some error found this tree will be killed */
3935 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3936 tree->opval.op = NULLOP;
3942 /*-----------------------------------------------------------------*/
3943 /* sizeofOp - processes size of operation */
3944 /*-----------------------------------------------------------------*/
3946 sizeofOp (sym_link * type)
3950 /* make sure the type is complete and sane */
3951 checkTypeSanity(type, "(sizeof)");
3953 /* get the size and convert it to character */
3954 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3956 /* now convert into value */
3957 return constVal (buff);
3961 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3962 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3963 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3964 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3965 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3966 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3967 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3969 /*-----------------------------------------------------------------*/
3970 /* backPatchLabels - change and or not operators to flow control */
3971 /*-----------------------------------------------------------------*/
3973 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3979 if (!(IS_ANDORNOT (tree)))
3982 /* if this an and */
3985 static int localLbl = 0;
3988 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3989 localLabel = newSymbol (buffer, NestLevel);
3991 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3993 /* if left is already a IFX then just change the if true label in that */
3994 if (!IS_IFX (tree->left))
3995 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3997 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3998 /* right is a IFX then just join */
3999 if (IS_IFX (tree->right))
4000 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4002 tree->right = createLabel (localLabel, tree->right);
4003 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4005 return newNode (NULLOP, tree->left, tree->right);
4008 /* if this is an or operation */
4011 static int localLbl = 0;
4014 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4015 localLabel = newSymbol (buffer, NestLevel);
4017 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4019 /* if left is already a IFX then just change the if true label in that */
4020 if (!IS_IFX (tree->left))
4021 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4023 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4024 /* right is a IFX then just join */
4025 if (IS_IFX (tree->right))
4026 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4028 tree->right = createLabel (localLabel, tree->right);
4029 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4031 return newNode (NULLOP, tree->left, tree->right);
4037 int wasnot = IS_NOT (tree->left);
4038 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4040 /* if the left is already a IFX */
4041 if (!IS_IFX (tree->left))
4042 tree->left = newNode (IFX, tree->left, NULL);
4046 tree->left->trueLabel = trueLabel;
4047 tree->left->falseLabel = falseLabel;
4051 tree->left->trueLabel = falseLabel;
4052 tree->left->falseLabel = trueLabel;
4059 tree->trueLabel = trueLabel;
4060 tree->falseLabel = falseLabel;
4067 /*-----------------------------------------------------------------*/
4068 /* createBlock - create expression tree for block */
4069 /*-----------------------------------------------------------------*/
4071 createBlock (symbol * decl, ast * body)
4075 /* if the block has nothing */
4079 ex = newNode (BLOCK, NULL, body);
4080 ex->values.sym = decl;
4082 ex->right = ex->right;
4088 /*-----------------------------------------------------------------*/
4089 /* createLabel - creates the expression tree for labels */
4090 /*-----------------------------------------------------------------*/
4092 createLabel (symbol * label, ast * stmnt)
4095 char name[SDCC_NAME_MAX + 1];
4098 /* must create fresh symbol if the symbol name */
4099 /* exists in the symbol table, since there can */
4100 /* be a variable with the same name as the labl */
4101 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4102 (csym->level == label->level))
4103 label = newSymbol (label->name, label->level);
4105 /* change the name before putting it in add _ */
4106 SNPRINTF(name, sizeof(name), "%s", label->name);
4108 /* put the label in the LabelSymbol table */
4109 /* but first check if a label of the same */
4111 if ((csym = findSym (LabelTab, NULL, name)))
4112 werror (E_DUPLICATE_LABEL, label->name);
4114 addSym (LabelTab, label, name, label->level, 0, 0);
4117 label->key = labelKey++;
4118 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4124 /*-----------------------------------------------------------------*/
4125 /* createCase - generates the parsetree for a case statement */
4126 /*-----------------------------------------------------------------*/
4128 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4130 char caseLbl[SDCC_NAME_MAX + 1];
4134 /* if the switch statement does not exist */
4135 /* then case is out of context */
4138 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4142 caseVal = decorateType (resolveSymbols (caseVal));
4143 /* if not a constant then error */
4144 if (!IS_LITERAL (caseVal->ftype))
4146 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4150 /* if not a integer than error */
4151 if (!IS_INTEGRAL (caseVal->ftype))
4153 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4157 /* find the end of the switch values chain */
4158 if (!(val = swStat->values.switchVals.swVals))
4159 swStat->values.switchVals.swVals = caseVal->opval.val;
4162 /* also order the cases according to value */
4164 int cVal = (int) floatFromVal (caseVal->opval.val);
4165 while (val && (int) floatFromVal (val) < cVal)
4171 /* if we reached the end then */
4174 pval->next = caseVal->opval.val;
4176 else if ((int) floatFromVal (val) == cVal)
4178 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4184 /* we found a value greater than */
4185 /* the current value we must add this */
4186 /* before the value */
4187 caseVal->opval.val->next = val;
4189 /* if this was the first in chain */
4190 if (swStat->values.switchVals.swVals == val)
4191 swStat->values.switchVals.swVals =
4194 pval->next = caseVal->opval.val;
4199 /* create the case label */
4200 SNPRINTF(caseLbl, sizeof(caseLbl),
4202 swStat->values.switchVals.swNum,
4203 (int) floatFromVal (caseVal->opval.val));
4205 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4210 /*-----------------------------------------------------------------*/
4211 /* createDefault - creates the parse tree for the default statement */
4212 /*-----------------------------------------------------------------*/
4214 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4216 char defLbl[SDCC_NAME_MAX + 1];
4218 /* if the switch statement does not exist */
4219 /* then case is out of context */
4222 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4226 if (swStat->values.switchVals.swDefault)
4228 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4233 /* turn on the default flag */
4234 swStat->values.switchVals.swDefault = 1;
4236 /* create the label */
4237 SNPRINTF (defLbl, sizeof(defLbl),
4238 "_default_%d", swStat->values.switchVals.swNum);
4239 return createLabel (newSymbol (defLbl, 0), stmnt);
4242 /*-----------------------------------------------------------------*/
4243 /* createIf - creates the parsetree for the if statement */
4244 /*-----------------------------------------------------------------*/
4246 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4248 static int Lblnum = 0;
4250 symbol *ifTrue, *ifFalse, *ifEnd;
4252 /* if neither exists */
4253 if (!elseBody && !ifBody) {
4254 // if there are no side effects (i++, j() etc)
4255 if (!hasSEFcalls(condAst)) {
4260 /* create the labels */
4261 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4262 ifFalse = newSymbol (buffer, NestLevel);
4263 /* if no else body then end == false */
4268 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4269 ifEnd = newSymbol (buffer, NestLevel);
4272 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4273 ifTrue = newSymbol (buffer, NestLevel);
4277 /* attach the ifTrue label to the top of it body */
4278 ifBody = createLabel (ifTrue, ifBody);
4279 /* attach a goto end to the ifBody if else is present */
4282 ifBody = newNode (NULLOP, ifBody,
4284 newAst_VALUE (symbolVal (ifEnd)),
4286 /* put the elseLabel on the else body */
4287 elseBody = createLabel (ifFalse, elseBody);
4288 /* out the end at the end of the body */
4289 elseBody = newNode (NULLOP,
4291 createLabel (ifEnd, NULL));
4295 ifBody = newNode (NULLOP, ifBody,
4296 createLabel (ifFalse, NULL));
4298 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4299 if (IS_IFX (condAst))
4302 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4304 return newNode (NULLOP, ifTree,
4305 newNode (NULLOP, ifBody, elseBody));
4309 /*-----------------------------------------------------------------*/
4310 /* createDo - creates parse tree for do */
4313 /* _docontinue_n: */
4314 /* condition_expression +-> trueLabel -> _dobody_n */
4316 /* +-> falseLabel-> _dobreak_n */
4318 /*-----------------------------------------------------------------*/
4320 createDo (symbol * trueLabel, symbol * continueLabel,
4321 symbol * falseLabel, ast * condAst, ast * doBody)
4326 /* if the body does not exist then it is simple */
4329 condAst = backPatchLabels (condAst, continueLabel, NULL);
4330 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4331 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4332 doTree->trueLabel = continueLabel;
4333 doTree->falseLabel = NULL;
4337 /* otherwise we have a body */
4338 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4340 /* attach the body label to the top */
4341 doBody = createLabel (trueLabel, doBody);
4342 /* attach the continue label to end of body */
4343 doBody = newNode (NULLOP, doBody,
4344 createLabel (continueLabel, NULL));
4346 /* now put the break label at the end */
4347 if (IS_IFX (condAst))
4350 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4352 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4354 /* putting it together */
4355 return newNode (NULLOP, doBody, doTree);
4358 /*-----------------------------------------------------------------*/
4359 /* createFor - creates parse tree for 'for' statement */
4362 /* condExpr +-> trueLabel -> _forbody_n */
4364 /* +-> falseLabel-> _forbreak_n */
4367 /* _forcontinue_n: */
4369 /* goto _forcond_n ; */
4371 /*-----------------------------------------------------------------*/
4373 createFor (symbol * trueLabel, symbol * continueLabel,
4374 symbol * falseLabel, symbol * condLabel,
4375 ast * initExpr, ast * condExpr, ast * loopExpr,
4380 /* if loopexpression not present then we can generate it */
4381 /* the same way as a while */
4383 return newNode (NULLOP, initExpr,
4384 createWhile (trueLabel, continueLabel,
4385 falseLabel, condExpr, forBody));
4386 /* vanilla for statement */
4387 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4389 if (condExpr && !IS_IFX (condExpr))
4390 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4393 /* attach condition label to condition */
4394 condExpr = createLabel (condLabel, condExpr);
4396 /* attach body label to body */
4397 forBody = createLabel (trueLabel, forBody);
4399 /* attach continue to forLoop expression & attach */
4400 /* goto the forcond @ and of loopExpression */
4401 loopExpr = createLabel (continueLabel,
4405 newAst_VALUE (symbolVal (condLabel)),
4407 /* now start putting them together */
4408 forTree = newNode (NULLOP, initExpr, condExpr);
4409 forTree = newNode (NULLOP, forTree, forBody);
4410 forTree = newNode (NULLOP, forTree, loopExpr);
4411 /* finally add the break label */
4412 forTree = newNode (NULLOP, forTree,
4413 createLabel (falseLabel, NULL));
4417 /*-----------------------------------------------------------------*/
4418 /* createWhile - creates parse tree for while statement */
4419 /* the while statement will be created as follows */
4421 /* _while_continue_n: */
4422 /* condition_expression +-> trueLabel -> _while_boby_n */
4424 /* +-> falseLabel -> _while_break_n */
4425 /* _while_body_n: */
4427 /* goto _while_continue_n */
4428 /* _while_break_n: */
4429 /*-----------------------------------------------------------------*/
4431 createWhile (symbol * trueLabel, symbol * continueLabel,
4432 symbol * falseLabel, ast * condExpr, ast * whileBody)
4436 /* put the continue label */
4437 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4438 condExpr = createLabel (continueLabel, condExpr);
4439 condExpr->lineno = 0;
4441 /* put the body label in front of the body */
4442 whileBody = createLabel (trueLabel, whileBody);
4443 whileBody->lineno = 0;
4444 /* put a jump to continue at the end of the body */
4445 /* and put break label at the end of the body */
4446 whileBody = newNode (NULLOP,
4449 newAst_VALUE (symbolVal (continueLabel)),
4450 createLabel (falseLabel, NULL)));
4452 /* put it all together */
4453 if (IS_IFX (condExpr))
4454 whileTree = condExpr;
4457 whileTree = newNode (IFX, condExpr, NULL);
4458 /* put the true & false labels in place */
4459 whileTree->trueLabel = trueLabel;
4460 whileTree->falseLabel = falseLabel;
4463 return newNode (NULLOP, whileTree, whileBody);
4466 /*-----------------------------------------------------------------*/
4467 /* optimizeGetHbit - get highest order bit of the expression */
4468 /*-----------------------------------------------------------------*/
4470 optimizeGetHbit (ast * tree)
4473 /* if this is not a bit and */
4474 if (!IS_BITAND (tree))
4477 /* will look for tree of the form
4478 ( expr >> ((sizeof expr) -1) ) & 1 */
4479 if (!IS_AST_LIT_VALUE (tree->right))
4482 if (AST_LIT_VALUE (tree->right) != 1)
4485 if (!IS_RIGHT_OP (tree->left))
4488 if (!IS_AST_LIT_VALUE (tree->left->right))
4491 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4492 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4495 /* make sure the port supports GETHBIT */
4496 if (port->hasExtBitOp
4497 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4500 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4504 /*-----------------------------------------------------------------*/
4505 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4506 /*-----------------------------------------------------------------*/
4508 optimizeRRCRLC (ast * root)
4510 /* will look for trees of the form
4511 (?expr << 1) | (?expr >> 7) or
4512 (?expr >> 7) | (?expr << 1) will make that
4513 into a RLC : operation ..
4515 (?expr >> 1) | (?expr << 7) or
4516 (?expr << 7) | (?expr >> 1) will make that
4517 into a RRC operation
4518 note : by 7 I mean (number of bits required to hold the
4520 /* if the root operations is not a | operation the not */
4521 if (!IS_BITOR (root))
4524 /* I have to think of a better way to match patterns this sucks */
4525 /* that aside let start looking for the first case : I use a the
4526 negative check a lot to improve the efficiency */
4527 /* (?expr << 1) | (?expr >> 7) */
4528 if (IS_LEFT_OP (root->left) &&
4529 IS_RIGHT_OP (root->right))
4532 if (!SPEC_USIGN (TETYPE (root->left->left)))
4535 if (!IS_AST_LIT_VALUE (root->left->right) ||
4536 !IS_AST_LIT_VALUE (root->right->right))
4539 /* make sure it is the same expression */
4540 if (!isAstEqual (root->left->left,
4544 if (AST_LIT_VALUE (root->left->right) != 1)
4547 if (AST_LIT_VALUE (root->right->right) !=
4548 (getSize (TTYPE (root->left->left)) * 8 - 1))
4551 /* make sure the port supports RLC */
4552 if (port->hasExtBitOp
4553 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4556 /* whew got the first case : create the AST */
4557 return newNode (RLC, root->left->left, NULL);
4561 /* check for second case */
4562 /* (?expr >> 7) | (?expr << 1) */
4563 if (IS_LEFT_OP (root->right) &&
4564 IS_RIGHT_OP (root->left))
4567 if (!SPEC_USIGN (TETYPE (root->left->left)))
4570 if (!IS_AST_LIT_VALUE (root->left->right) ||
4571 !IS_AST_LIT_VALUE (root->right->right))
4574 /* make sure it is the same symbol */
4575 if (!isAstEqual (root->left->left,
4579 if (AST_LIT_VALUE (root->right->right) != 1)
4582 if (AST_LIT_VALUE (root->left->right) !=
4583 (getSize (TTYPE (root->left->left)) * 8 - 1))
4586 /* make sure the port supports RLC */
4587 if (port->hasExtBitOp
4588 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4591 /* whew got the first case : create the AST */
4592 return newNode (RLC, root->left->left, NULL);
4597 /* third case for RRC */
4598 /* (?symbol >> 1) | (?symbol << 7) */
4599 if (IS_LEFT_OP (root->right) &&
4600 IS_RIGHT_OP (root->left))
4603 if (!SPEC_USIGN (TETYPE (root->left->left)))
4606 if (!IS_AST_LIT_VALUE (root->left->right) ||
4607 !IS_AST_LIT_VALUE (root->right->right))
4610 /* make sure it is the same symbol */
4611 if (!isAstEqual (root->left->left,
4615 if (AST_LIT_VALUE (root->left->right) != 1)
4618 if (AST_LIT_VALUE (root->right->right) !=
4619 (getSize (TTYPE (root->left->left)) * 8 - 1))
4622 /* make sure the port supports RRC */
4623 if (port->hasExtBitOp
4624 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4627 /* whew got the first case : create the AST */
4628 return newNode (RRC, root->left->left, NULL);
4632 /* fourth and last case for now */
4633 /* (?symbol << 7) | (?symbol >> 1) */
4634 if (IS_RIGHT_OP (root->right) &&
4635 IS_LEFT_OP (root->left))
4638 if (!SPEC_USIGN (TETYPE (root->left->left)))
4641 if (!IS_AST_LIT_VALUE (root->left->right) ||
4642 !IS_AST_LIT_VALUE (root->right->right))
4645 /* make sure it is the same symbol */
4646 if (!isAstEqual (root->left->left,
4650 if (AST_LIT_VALUE (root->right->right) != 1)
4653 if (AST_LIT_VALUE (root->left->right) !=
4654 (getSize (TTYPE (root->left->left)) * 8 - 1))
4657 /* make sure the port supports RRC */
4658 if (port->hasExtBitOp
4659 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4662 /* whew got the first case : create the AST */
4663 return newNode (RRC, root->left->left, NULL);
4667 /* not found return root */
4671 /*-----------------------------------------------------------------*/
4672 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4673 /*-----------------------------------------------------------------*/
4675 optimizeSWAP (ast * root)
4677 /* will look for trees of the form
4678 (?expr << 4) | (?expr >> 4) or
4679 (?expr >> 4) | (?expr << 4) will make that
4680 into a SWAP : operation ..
4681 note : by 4 I mean (number of bits required to hold the
4683 /* if the root operations is not a | operation the not */
4684 if (!IS_BITOR (root))
4687 /* (?expr << 4) | (?expr >> 4) */
4688 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4689 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4692 if (!SPEC_USIGN (TETYPE (root->left->left)))
4695 if (!IS_AST_LIT_VALUE (root->left->right) ||
4696 !IS_AST_LIT_VALUE (root->right->right))
4699 /* make sure it is the same expression */
4700 if (!isAstEqual (root->left->left,
4704 if (AST_LIT_VALUE (root->left->right) !=
4705 (getSize (TTYPE (root->left->left)) * 4))
4708 if (AST_LIT_VALUE (root->right->right) !=
4709 (getSize (TTYPE (root->left->left)) * 4))
4712 /* make sure the port supports SWAP */
4713 if (port->hasExtBitOp
4714 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4717 /* found it : create the AST */
4718 return newNode (SWAP, root->left->left, NULL);
4722 /* not found return root */
4726 /*-----------------------------------------------------------------*/
4727 /* optimizeCompare - otimizes compares for bit variables */
4728 /*-----------------------------------------------------------------*/
4730 optimizeCompare (ast * root)
4732 ast *optExpr = NULL;
4735 unsigned int litValue;
4737 /* if nothing then return nothing */
4741 /* if not a compare op then do leaves */
4742 if (!IS_COMPARE_OP (root))
4744 root->left = optimizeCompare (root->left);
4745 root->right = optimizeCompare (root->right);
4749 /* if left & right are the same then depending
4750 of the operation do */
4751 if (isAstEqual (root->left, root->right))
4753 switch (root->opval.op)
4758 optExpr = newAst_VALUE (constVal ("0"));
4763 optExpr = newAst_VALUE (constVal ("1"));
4767 return decorateType (optExpr);
4770 vleft = (root->left->type == EX_VALUE ?
4771 root->left->opval.val : NULL);
4773 vright = (root->right->type == EX_VALUE ?
4774 root->right->opval.val : NULL);
4776 /* if left is a BITVAR in BITSPACE */
4777 /* and right is a LITERAL then opt- */
4778 /* imize else do nothing */
4779 if (vleft && vright &&
4780 IS_BITVAR (vleft->etype) &&
4781 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4782 IS_LITERAL (vright->etype))
4785 /* if right side > 1 then comparison may never succeed */
4786 if ((litValue = (int) floatFromVal (vright)) > 1)
4788 werror (W_BAD_COMPARE);
4794 switch (root->opval.op)
4796 case '>': /* bit value greater than 1 cannot be */
4797 werror (W_BAD_COMPARE);
4801 case '<': /* bit value < 1 means 0 */
4803 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4806 case LE_OP: /* bit value <= 1 means no check */
4807 optExpr = newAst_VALUE (vright);
4810 case GE_OP: /* bit value >= 1 means only check for = */
4812 optExpr = newAst_VALUE (vleft);
4817 { /* literal is zero */
4818 switch (root->opval.op)
4820 case '<': /* bit value < 0 cannot be */
4821 werror (W_BAD_COMPARE);
4825 case '>': /* bit value > 0 means 1 */
4827 optExpr = newAst_VALUE (vleft);
4830 case LE_OP: /* bit value <= 0 means no check */
4831 case GE_OP: /* bit value >= 0 means no check */
4832 werror (W_BAD_COMPARE);
4836 case EQ_OP: /* bit == 0 means ! of bit */
4837 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4841 return decorateType (resolveSymbols (optExpr));
4842 } /* end-of-if of BITVAR */
4847 /*-----------------------------------------------------------------*/
4848 /* addSymToBlock : adds the symbol to the first block we find */
4849 /*-----------------------------------------------------------------*/
4851 addSymToBlock (symbol * sym, ast * tree)
4853 /* reached end of tree or a leaf */
4854 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4858 if (IS_AST_OP (tree) &&
4859 tree->opval.op == BLOCK)
4862 symbol *lsym = copySymbol (sym);
4864 lsym->next = AST_VALUES (tree, sym);
4865 AST_VALUES (tree, sym) = lsym;
4869 addSymToBlock (sym, tree->left);
4870 addSymToBlock (sym, tree->right);
4873 /*-----------------------------------------------------------------*/
4874 /* processRegParms - do processing for register parameters */
4875 /*-----------------------------------------------------------------*/
4877 processRegParms (value * args, ast * body)
4881 if (IS_REGPARM (args->etype))
4882 addSymToBlock (args->sym, body);
4887 /*-----------------------------------------------------------------*/
4888 /* resetParmKey - resets the operandkeys for the symbols */
4889 /*-----------------------------------------------------------------*/
4890 DEFSETFUNC (resetParmKey)
4901 /*-----------------------------------------------------------------*/
4902 /* createFunction - This is the key node that calls the iCode for */
4903 /* generating the code for a function. Note code */
4904 /* is generated function by function, later when */
4905 /* add inter-procedural analysis this will change */
4906 /*-----------------------------------------------------------------*/
4908 createFunction (symbol * name, ast * body)
4914 iCode *piCode = NULL;
4916 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4917 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4919 /* if check function return 0 then some problem */
4920 if (checkFunction (name, NULL) == 0)
4923 /* create a dummy block if none exists */
4925 body = newNode (BLOCK, NULL, NULL);
4929 /* check if the function name already in the symbol table */
4930 if ((csym = findSym (SymbolTab, NULL, name->name)))
4933 /* special case for compiler defined functions
4934 we need to add the name to the publics list : this
4935 actually means we are now compiling the compiler
4939 addSet (&publics, name);
4945 allocVariables (name);
4947 name->lastLine = mylineno;
4950 /* set the stack pointer */
4951 /* PENDING: check this for the mcs51 */
4952 stackPtr = -port->stack.direction * port->stack.call_overhead;
4953 if (IFFUNC_ISISR (name->type))
4954 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4955 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4956 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4958 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4960 fetype = getSpec (name->type); /* get the specifier for the function */
4961 /* if this is a reentrant function then */
4962 if (IFFUNC_ISREENT (name->type))
4965 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4967 /* do processing for parameters that are passed in registers */
4968 processRegParms (FUNC_ARGS(name->type), body);
4970 /* set the stack pointer */
4974 /* allocate & autoinit the block variables */
4975 processBlockVars (body, &stack, ALLOCATE);
4977 /* save the stack information */
4978 if (options.useXstack)
4979 name->xstack = SPEC_STAK (fetype) = stack;
4981 name->stack = SPEC_STAK (fetype) = stack;
4983 /* name needs to be mangled */
4984 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4986 body = resolveSymbols (body); /* resolve the symbols */
4987 body = decorateType (body); /* propagateType & do semantic checks */
4989 ex = newAst_VALUE (symbolVal (name)); /* create name */
4990 ex = newNode (FUNCTION, ex, body);
4991 ex->values.args = FUNC_ARGS(name->type);
4993 if (options.dump_tree) PA(ex);
4996 werror (E_FUNC_NO_CODE, name->name);
5000 /* create the node & generate intermediate code */
5002 codeOutFile = code->oFile;
5003 piCode = iCodeFromAst (ex);
5007 werror (E_FUNC_NO_CODE, name->name);
5011 eBBlockFromiCode (piCode);
5013 /* if there are any statics then do them */
5016 GcurMemmap = statsg;
5017 codeOutFile = statsg->oFile;
5018 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
5024 /* dealloc the block variables */
5025 processBlockVars (body, &stack, DEALLOCATE);
5026 outputDebugStackSymbols();
5027 /* deallocate paramaters */
5028 deallocParms (FUNC_ARGS(name->type));
5030 if (IFFUNC_ISREENT (name->type))
5033 /* we are done freeup memory & cleanup */
5035 if (port->reset_labelKey) labelKey = 1;
5037 FUNC_HASBODY(name->type) = 1;
5038 addSet (&operKeyReset, name);
5039 applyToSet (operKeyReset, resetParmKey);
5044 cleanUpLevel (LabelTab, 0);
5045 cleanUpBlock (StructTab, 1);
5046 cleanUpBlock (TypedefTab, 1);
5048 xstack->syms = NULL;
5049 istack->syms = NULL;
5054 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5055 /*-----------------------------------------------------------------*/
5056 /* ast_print : prints the ast (for debugging purposes) */
5057 /*-----------------------------------------------------------------*/
5059 void ast_print (ast * tree, FILE *outfile, int indent)
5064 /* can print only decorated trees */
5065 if (!tree->decorated) return;
5067 /* if any child is an error | this one is an error do nothing */
5068 if (tree->isError ||
5069 (tree->left && tree->left->isError) ||
5070 (tree->right && tree->right->isError)) {
5071 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5075 /* print the line */
5076 /* if not block & function */
5077 if (tree->type == EX_OP &&
5078 (tree->opval.op != FUNCTION &&
5079 tree->opval.op != BLOCK &&
5080 tree->opval.op != NULLOP)) {
5083 if (tree->opval.op == FUNCTION) {
5085 value *args=FUNC_ARGS(tree->left->opval.val->type);
5086 fprintf(outfile,"FUNCTION (%s=%p) type (",
5087 tree->left->opval.val->name, tree);
5088 printTypeChain (tree->left->opval.val->type->next,outfile);
5089 fprintf(outfile,") args (");
5092 fprintf (outfile, ", ");
5094 printTypeChain (args ? args->type : NULL, outfile);
5096 args= args ? args->next : NULL;
5098 fprintf(outfile,")\n");
5099 ast_print(tree->left,outfile,indent);
5100 ast_print(tree->right,outfile,indent);
5103 if (tree->opval.op == BLOCK) {
5104 symbol *decls = tree->values.sym;
5105 INDENT(indent,outfile);
5106 fprintf(outfile,"{\n");
5108 INDENT(indent+2,outfile);
5109 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5110 decls->name, decls);
5111 printTypeChain(decls->type,outfile);
5112 fprintf(outfile,")\n");
5114 decls = decls->next;
5116 ast_print(tree->right,outfile,indent+2);
5117 INDENT(indent,outfile);
5118 fprintf(outfile,"}\n");
5121 if (tree->opval.op == NULLOP) {
5122 ast_print(tree->left,outfile,indent);
5123 ast_print(tree->right,outfile,indent);
5126 INDENT(indent,outfile);
5128 /*------------------------------------------------------------------*/
5129 /*----------------------------*/
5130 /* leaf has been reached */
5131 /*----------------------------*/
5132 /* if this is of type value */
5133 /* just get the type */
5134 if (tree->type == EX_VALUE) {
5136 if (IS_LITERAL (tree->opval.val->etype)) {
5137 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5138 if (SPEC_USIGN (tree->opval.val->etype))
5139 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5141 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5142 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5143 floatFromVal(tree->opval.val));
5144 } else if (tree->opval.val->sym) {
5145 /* if the undefined flag is set then give error message */
5146 if (tree->opval.val->sym->undefined) {
5147 fprintf(outfile,"UNDEFINED SYMBOL ");
5149 fprintf(outfile,"SYMBOL ");
5151 fprintf(outfile,"(%s=%p)",
5152 tree->opval.val->sym->name,tree);
5155 fprintf(outfile," type (");
5156 printTypeChain(tree->ftype,outfile);
5157 fprintf(outfile,")\n");
5159 fprintf(outfile,"\n");
5164 /* if type link for the case of cast */
5165 if (tree->type == EX_LINK) {
5166 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5167 printTypeChain(tree->opval.lnk,outfile);
5168 fprintf(outfile,")\n");
5173 /* depending on type of operator do */
5175 switch (tree->opval.op) {
5176 /*------------------------------------------------------------------*/
5177 /*----------------------------*/
5179 /*----------------------------*/
5181 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5182 printTypeChain(tree->ftype,outfile);
5183 fprintf(outfile,")\n");
5184 ast_print(tree->left,outfile,indent+2);
5185 ast_print(tree->right,outfile,indent+2);
5188 /*------------------------------------------------------------------*/
5189 /*----------------------------*/
5191 /*----------------------------*/
5193 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5194 printTypeChain(tree->ftype,outfile);
5195 fprintf(outfile,")\n");
5196 ast_print(tree->left,outfile,indent+2);
5197 ast_print(tree->right,outfile,indent+2);
5200 /*------------------------------------------------------------------*/
5201 /*----------------------------*/
5202 /* struct/union pointer */
5203 /*----------------------------*/
5205 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5206 printTypeChain(tree->ftype,outfile);
5207 fprintf(outfile,")\n");
5208 ast_print(tree->left,outfile,indent+2);
5209 ast_print(tree->right,outfile,indent+2);
5212 /*------------------------------------------------------------------*/
5213 /*----------------------------*/
5214 /* ++/-- operation */
5215 /*----------------------------*/
5218 fprintf(outfile,"post-");
5220 fprintf(outfile,"pre-");
5221 fprintf(outfile,"INC_OP (%p) type (",tree);
5222 printTypeChain(tree->ftype,outfile);
5223 fprintf(outfile,")\n");
5224 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5225 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5230 fprintf(outfile,"post-");
5232 fprintf(outfile,"pre-");
5233 fprintf(outfile,"DEC_OP (%p) type (",tree);
5234 printTypeChain(tree->ftype,outfile);
5235 fprintf(outfile,")\n");
5236 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5237 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5240 /*------------------------------------------------------------------*/
5241 /*----------------------------*/
5243 /*----------------------------*/
5246 fprintf(outfile,"& (%p) type (",tree);
5247 printTypeChain(tree->ftype,outfile);
5248 fprintf(outfile,")\n");
5249 ast_print(tree->left,outfile,indent+2);
5250 ast_print(tree->right,outfile,indent+2);
5252 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5253 printTypeChain(tree->ftype,outfile);
5254 fprintf(outfile,")\n");
5255 ast_print(tree->left,outfile,indent+2);
5256 ast_print(tree->right,outfile,indent+2);
5259 /*----------------------------*/
5261 /*----------------------------*/
5263 fprintf(outfile,"OR (%p) type (",tree);
5264 printTypeChain(tree->ftype,outfile);
5265 fprintf(outfile,")\n");
5266 ast_print(tree->left,outfile,indent+2);
5267 ast_print(tree->right,outfile,indent+2);
5269 /*------------------------------------------------------------------*/
5270 /*----------------------------*/
5272 /*----------------------------*/
5274 fprintf(outfile,"XOR (%p) type (",tree);
5275 printTypeChain(tree->ftype,outfile);
5276 fprintf(outfile,")\n");
5277 ast_print(tree->left,outfile,indent+2);
5278 ast_print(tree->right,outfile,indent+2);
5281 /*------------------------------------------------------------------*/
5282 /*----------------------------*/
5284 /*----------------------------*/
5286 fprintf(outfile,"DIV (%p) type (",tree);
5287 printTypeChain(tree->ftype,outfile);
5288 fprintf(outfile,")\n");
5289 ast_print(tree->left,outfile,indent+2);
5290 ast_print(tree->right,outfile,indent+2);
5292 /*------------------------------------------------------------------*/
5293 /*----------------------------*/
5295 /*----------------------------*/
5297 fprintf(outfile,"MOD (%p) type (",tree);
5298 printTypeChain(tree->ftype,outfile);
5299 fprintf(outfile,")\n");
5300 ast_print(tree->left,outfile,indent+2);
5301 ast_print(tree->right,outfile,indent+2);
5304 /*------------------------------------------------------------------*/
5305 /*----------------------------*/
5306 /* address dereference */
5307 /*----------------------------*/
5308 case '*': /* can be unary : if right is null then unary operation */
5310 fprintf(outfile,"DEREF (%p) type (",tree);
5311 printTypeChain(tree->ftype,outfile);
5312 fprintf(outfile,")\n");
5313 ast_print(tree->left,outfile,indent+2);
5316 /*------------------------------------------------------------------*/
5317 /*----------------------------*/
5318 /* multiplication */
5319 /*----------------------------*/
5320 fprintf(outfile,"MULT (%p) type (",tree);
5321 printTypeChain(tree->ftype,outfile);
5322 fprintf(outfile,")\n");
5323 ast_print(tree->left,outfile,indent+2);
5324 ast_print(tree->right,outfile,indent+2);
5328 /*------------------------------------------------------------------*/
5329 /*----------------------------*/
5330 /* unary '+' operator */
5331 /*----------------------------*/
5335 fprintf(outfile,"UPLUS (%p) type (",tree);
5336 printTypeChain(tree->ftype,outfile);
5337 fprintf(outfile,")\n");
5338 ast_print(tree->left,outfile,indent+2);
5340 /*------------------------------------------------------------------*/
5341 /*----------------------------*/
5343 /*----------------------------*/
5344 fprintf(outfile,"ADD (%p) type (",tree);
5345 printTypeChain(tree->ftype,outfile);
5346 fprintf(outfile,")\n");
5347 ast_print(tree->left,outfile,indent+2);
5348 ast_print(tree->right,outfile,indent+2);
5351 /*------------------------------------------------------------------*/
5352 /*----------------------------*/
5354 /*----------------------------*/
5355 case '-': /* can be unary */
5357 fprintf(outfile,"UMINUS (%p) type (",tree);
5358 printTypeChain(tree->ftype,outfile);
5359 fprintf(outfile,")\n");
5360 ast_print(tree->left,outfile,indent+2);
5362 /*------------------------------------------------------------------*/
5363 /*----------------------------*/
5365 /*----------------------------*/
5366 fprintf(outfile,"SUB (%p) type (",tree);
5367 printTypeChain(tree->ftype,outfile);
5368 fprintf(outfile,")\n");
5369 ast_print(tree->left,outfile,indent+2);
5370 ast_print(tree->right,outfile,indent+2);
5373 /*------------------------------------------------------------------*/
5374 /*----------------------------*/
5376 /*----------------------------*/
5378 fprintf(outfile,"COMPL (%p) type (",tree);
5379 printTypeChain(tree->ftype,outfile);
5380 fprintf(outfile,")\n");
5381 ast_print(tree->left,outfile,indent+2);
5383 /*------------------------------------------------------------------*/
5384 /*----------------------------*/
5386 /*----------------------------*/
5388 fprintf(outfile,"NOT (%p) type (",tree);
5389 printTypeChain(tree->ftype,outfile);
5390 fprintf(outfile,")\n");
5391 ast_print(tree->left,outfile,indent+2);
5393 /*------------------------------------------------------------------*/
5394 /*----------------------------*/
5396 /*----------------------------*/
5398 fprintf(outfile,"RRC (%p) type (",tree);
5399 printTypeChain(tree->ftype,outfile);
5400 fprintf(outfile,")\n");
5401 ast_print(tree->left,outfile,indent+2);
5405 fprintf(outfile,"RLC (%p) type (",tree);
5406 printTypeChain(tree->ftype,outfile);
5407 fprintf(outfile,")\n");
5408 ast_print(tree->left,outfile,indent+2);
5411 fprintf(outfile,"SWAP (%p) type (",tree);
5412 printTypeChain(tree->ftype,outfile);
5413 fprintf(outfile,")\n");
5414 ast_print(tree->left,outfile,indent+2);
5417 fprintf(outfile,"GETHBIT (%p) type (",tree);
5418 printTypeChain(tree->ftype,outfile);
5419 fprintf(outfile,")\n");
5420 ast_print(tree->left,outfile,indent+2);
5423 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5424 printTypeChain(tree->ftype,outfile);
5425 fprintf(outfile,")\n");
5426 ast_print(tree->left,outfile,indent+2);
5427 ast_print(tree->right,outfile,indent+2);
5430 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5431 printTypeChain(tree->ftype,outfile);
5432 fprintf(outfile,")\n");
5433 ast_print(tree->left,outfile,indent+2);
5434 ast_print(tree->right,outfile,indent+2);
5436 /*------------------------------------------------------------------*/
5437 /*----------------------------*/
5439 /*----------------------------*/
5440 case CAST: /* change the type */
5441 fprintf(outfile,"CAST (%p) from type (",tree);
5442 printTypeChain(tree->right->ftype,outfile);
5443 fprintf(outfile,") to type (");
5444 printTypeChain(tree->ftype,outfile);
5445 fprintf(outfile,")\n");
5446 ast_print(tree->right,outfile,indent+2);
5450 fprintf(outfile,"ANDAND (%p) type (",tree);
5451 printTypeChain(tree->ftype,outfile);
5452 fprintf(outfile,")\n");
5453 ast_print(tree->left,outfile,indent+2);
5454 ast_print(tree->right,outfile,indent+2);
5457 fprintf(outfile,"OROR (%p) type (",tree);
5458 printTypeChain(tree->ftype,outfile);
5459 fprintf(outfile,")\n");
5460 ast_print(tree->left,outfile,indent+2);
5461 ast_print(tree->right,outfile,indent+2);
5464 /*------------------------------------------------------------------*/
5465 /*----------------------------*/
5466 /* comparison operators */
5467 /*----------------------------*/
5469 fprintf(outfile,"GT(>) (%p) type (",tree);
5470 printTypeChain(tree->ftype,outfile);
5471 fprintf(outfile,")\n");
5472 ast_print(tree->left,outfile,indent+2);
5473 ast_print(tree->right,outfile,indent+2);
5476 fprintf(outfile,"LT(<) (%p) type (",tree);
5477 printTypeChain(tree->ftype,outfile);
5478 fprintf(outfile,")\n");
5479 ast_print(tree->left,outfile,indent+2);
5480 ast_print(tree->right,outfile,indent+2);
5483 fprintf(outfile,"LE(<=) (%p) type (",tree);
5484 printTypeChain(tree->ftype,outfile);
5485 fprintf(outfile,")\n");
5486 ast_print(tree->left,outfile,indent+2);
5487 ast_print(tree->right,outfile,indent+2);
5490 fprintf(outfile,"GE(>=) (%p) type (",tree);
5491 printTypeChain(tree->ftype,outfile);
5492 fprintf(outfile,")\n");
5493 ast_print(tree->left,outfile,indent+2);
5494 ast_print(tree->right,outfile,indent+2);
5497 fprintf(outfile,"EQ(==) (%p) type (",tree);
5498 printTypeChain(tree->ftype,outfile);
5499 fprintf(outfile,")\n");
5500 ast_print(tree->left,outfile,indent+2);
5501 ast_print(tree->right,outfile,indent+2);
5504 fprintf(outfile,"NE(!=) (%p) type (",tree);
5505 printTypeChain(tree->ftype,outfile);
5506 fprintf(outfile,")\n");
5507 ast_print(tree->left,outfile,indent+2);
5508 ast_print(tree->right,outfile,indent+2);
5509 /*------------------------------------------------------------------*/
5510 /*----------------------------*/
5512 /*----------------------------*/
5513 case SIZEOF: /* evaluate wihout code generation */
5514 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5517 /*------------------------------------------------------------------*/
5518 /*----------------------------*/
5519 /* conditional operator '?' */
5520 /*----------------------------*/
5522 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5523 printTypeChain(tree->ftype,outfile);
5524 fprintf(outfile,")\n");
5525 ast_print(tree->left,outfile,indent+2);
5526 ast_print(tree->right,outfile,indent+2);
5530 fprintf(outfile,"COLON(:) (%p) type (",tree);
5531 printTypeChain(tree->ftype,outfile);
5532 fprintf(outfile,")\n");
5533 ast_print(tree->left,outfile,indent+2);
5534 ast_print(tree->right,outfile,indent+2);
5537 /*------------------------------------------------------------------*/
5538 /*----------------------------*/
5539 /* assignment operators */
5540 /*----------------------------*/
5542 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5543 printTypeChain(tree->ftype,outfile);
5544 fprintf(outfile,")\n");
5545 ast_print(tree->left,outfile,indent+2);
5546 ast_print(tree->right,outfile,indent+2);
5549 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5550 printTypeChain(tree->ftype,outfile);
5551 fprintf(outfile,")\n");
5552 ast_print(tree->left,outfile,indent+2);
5553 ast_print(tree->right,outfile,indent+2);
5556 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5557 printTypeChain(tree->ftype,outfile);
5558 fprintf(outfile,")\n");
5559 ast_print(tree->left,outfile,indent+2);
5560 ast_print(tree->right,outfile,indent+2);
5563 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5564 printTypeChain(tree->ftype,outfile);
5565 fprintf(outfile,")\n");
5566 ast_print(tree->left,outfile,indent+2);
5567 ast_print(tree->right,outfile,indent+2);
5570 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5571 printTypeChain(tree->ftype,outfile);
5572 fprintf(outfile,")\n");
5573 ast_print(tree->left,outfile,indent+2);
5574 ast_print(tree->right,outfile,indent+2);
5577 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5578 printTypeChain(tree->ftype,outfile);
5579 fprintf(outfile,")\n");
5580 ast_print(tree->left,outfile,indent+2);
5581 ast_print(tree->right,outfile,indent+2);
5584 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5585 printTypeChain(tree->ftype,outfile);
5586 fprintf(outfile,")\n");
5587 ast_print(tree->left,outfile,indent+2);
5588 ast_print(tree->right,outfile,indent+2);
5590 /*------------------------------------------------------------------*/
5591 /*----------------------------*/
5593 /*----------------------------*/
5595 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5596 printTypeChain(tree->ftype,outfile);
5597 fprintf(outfile,")\n");
5598 ast_print(tree->left,outfile,indent+2);
5599 ast_print(tree->right,outfile,indent+2);
5601 /*------------------------------------------------------------------*/
5602 /*----------------------------*/
5604 /*----------------------------*/
5606 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5607 printTypeChain(tree->ftype,outfile);
5608 fprintf(outfile,")\n");
5609 ast_print(tree->left,outfile,indent+2);
5610 ast_print(tree->right,outfile,indent+2);
5612 /*------------------------------------------------------------------*/
5613 /*----------------------------*/
5614 /* straight assignemnt */
5615 /*----------------------------*/
5617 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5618 printTypeChain(tree->ftype,outfile);
5619 fprintf(outfile,")\n");
5620 ast_print(tree->left,outfile,indent+2);
5621 ast_print(tree->right,outfile,indent+2);
5623 /*------------------------------------------------------------------*/
5624 /*----------------------------*/
5625 /* comma operator */
5626 /*----------------------------*/
5628 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5629 printTypeChain(tree->ftype,outfile);
5630 fprintf(outfile,")\n");
5631 ast_print(tree->left,outfile,indent+2);
5632 ast_print(tree->right,outfile,indent+2);
5634 /*------------------------------------------------------------------*/
5635 /*----------------------------*/
5637 /*----------------------------*/
5640 fprintf(outfile,"CALL (%p) type (",tree);
5641 printTypeChain(tree->ftype,outfile);
5642 fprintf(outfile,")\n");
5643 ast_print(tree->left,outfile,indent+2);
5644 ast_print(tree->right,outfile,indent+2);
5647 fprintf(outfile,"PARMS\n");
5648 ast_print(tree->left,outfile,indent+2);
5649 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5650 ast_print(tree->right,outfile,indent+2);
5653 /*------------------------------------------------------------------*/
5654 /*----------------------------*/
5655 /* return statement */
5656 /*----------------------------*/
5658 fprintf(outfile,"RETURN (%p) type (",tree);
5660 printTypeChain(tree->right->ftype,outfile);
5662 fprintf(outfile,")\n");
5663 ast_print(tree->right,outfile,indent+2);
5665 /*------------------------------------------------------------------*/
5666 /*----------------------------*/
5667 /* label statement */
5668 /*----------------------------*/
5670 fprintf(outfile,"LABEL (%p)\n",tree);
5671 ast_print(tree->left,outfile,indent+2);
5672 ast_print(tree->right,outfile,indent);
5674 /*------------------------------------------------------------------*/
5675 /*----------------------------*/
5676 /* switch statement */
5677 /*----------------------------*/
5681 fprintf(outfile,"SWITCH (%p) ",tree);
5682 ast_print(tree->left,outfile,0);
5683 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5684 INDENT(indent+2,outfile);
5685 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5686 (int) floatFromVal(val),
5687 tree->values.switchVals.swNum,
5688 (int) floatFromVal(val));
5690 ast_print(tree->right,outfile,indent);
5693 /*------------------------------------------------------------------*/
5694 /*----------------------------*/
5696 /*----------------------------*/
5698 fprintf(outfile,"IF (%p) \n",tree);
5699 ast_print(tree->left,outfile,indent+2);
5700 if (tree->trueLabel) {
5701 INDENT(indent+2,outfile);
5702 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5704 if (tree->falseLabel) {
5705 INDENT(indent+2,outfile);
5706 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5708 ast_print(tree->right,outfile,indent+2);
5710 /*----------------------------*/
5711 /* goto Statement */
5712 /*----------------------------*/
5714 fprintf(outfile,"GOTO (%p) \n",tree);
5715 ast_print(tree->left,outfile,indent+2);
5716 fprintf(outfile,"\n");
5718 /*------------------------------------------------------------------*/
5719 /*----------------------------*/
5721 /*----------------------------*/
5723 fprintf(outfile,"FOR (%p) \n",tree);
5724 if (AST_FOR( tree, initExpr)) {
5725 INDENT(indent+2,outfile);
5726 fprintf(outfile,"INIT EXPR ");
5727 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5729 if (AST_FOR( tree, condExpr)) {
5730 INDENT(indent+2,outfile);
5731 fprintf(outfile,"COND EXPR ");
5732 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5734 if (AST_FOR( tree, loopExpr)) {
5735 INDENT(indent+2,outfile);
5736 fprintf(outfile,"LOOP EXPR ");
5737 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5739 fprintf(outfile,"FOR LOOP BODY \n");
5740 ast_print(tree->left,outfile,indent+2);
5743 fprintf(outfile,"CRITICAL (%p) \n",tree);
5744 ast_print(tree->left,outfile,indent+2);
5752 ast_print(t,stdout,0);
5757 /*-----------------------------------------------------------------*/
5758 /* astErrors : returns non-zero if errors present in tree */
5759 /*-----------------------------------------------------------------*/
5760 int astErrors(ast *t)
5769 if (t->type == EX_VALUE
5770 && t->opval.val->sym
5771 && t->opval.val->sym->undefined)
5774 errors += astErrors(t->left);
5775 errors += astErrors(t->right);