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);
1000 rast = newNode (NULLOP,
1004 newAst_VALUE (valueFromLit ((float) i))),
1005 newAst_VALUE (valueFromLit (*s))));
1009 // now WE don't need iexpr's symbol anymore
1010 freeStringSymbol(AST_SYMBOL(iexpr));
1012 return decorateType (resolveSymbols (rast));
1018 /*-----------------------------------------------------------------*/
1019 /* createIvalPtr - generates initial value for pointers */
1020 /*-----------------------------------------------------------------*/
1022 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1028 if (ilist->type == INIT_DEEP)
1029 ilist = ilist->init.deep;
1031 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1033 /* if character pointer */
1034 if (IS_CHAR (type->next))
1035 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1038 return newNode ('=', sym, iexpr);
1041 /*-----------------------------------------------------------------*/
1042 /* createIval - generates code for initial value */
1043 /*-----------------------------------------------------------------*/
1045 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1052 /* if structure then */
1053 if (IS_STRUCT (type))
1054 rast = createIvalStruct (sym, type, ilist);
1056 /* if this is a pointer */
1058 rast = createIvalPtr (sym, type, ilist);
1060 /* if this is an array */
1061 if (IS_ARRAY (type))
1062 rast = createIvalArray (sym, type, ilist);
1064 /* if type is SPECIFIER */
1066 rast = createIvalType (sym, type, ilist);
1069 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1071 return decorateType (resolveSymbols (rast));
1074 /*-----------------------------------------------------------------*/
1075 /* initAggregates - initialises aggregate variables with initv */
1076 /*-----------------------------------------------------------------*/
1077 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1078 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1081 /*-----------------------------------------------------------------*/
1082 /* gatherAutoInit - creates assignment expressions for initial */
1084 /*-----------------------------------------------------------------*/
1086 gatherAutoInit (symbol * autoChain)
1093 for (sym = autoChain; sym; sym = sym->next)
1096 /* resolve the symbols in the ival */
1098 resolveIvalSym (sym->ival);
1100 /* if this is a static variable & has an */
1101 /* initial value the code needs to be lifted */
1102 /* here to the main portion since they can be */
1103 /* initialised only once at the start */
1104 if (IS_STATIC (sym->etype) && sym->ival &&
1105 SPEC_SCLS (sym->etype) != S_CODE)
1109 /* insert the symbol into the symbol table */
1110 /* with level = 0 & name = rname */
1111 newSym = copySymbol (sym);
1112 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1114 /* now lift the code to main */
1115 if (IS_AGGREGATE (sym->type)) {
1116 work = initAggregates (sym, sym->ival, NULL);
1118 if (getNelements(sym->type, sym->ival)>1) {
1119 werrorfl (filename, sym->lineDef,
1120 W_EXCESS_INITIALIZERS, "scalar",
1123 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1124 list2expr (sym->ival));
1127 setAstLineno (work, sym->lineDef);
1131 staticAutos = newNode (NULLOP, staticAutos, work);
1138 /* if there is an initial value */
1139 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1141 initList *ilist=sym->ival;
1143 while (ilist->type == INIT_DEEP) {
1144 ilist = ilist->init.deep;
1147 /* update lineno for error msg */
1148 lineno=sym->lineDef;
1149 setAstLineno (ilist->init.node, lineno);
1151 if (IS_AGGREGATE (sym->type)) {
1152 work = initAggregates (sym, sym->ival, NULL);
1154 if (getNelements(sym->type, sym->ival)>1) {
1155 werrorfl (filename, sym->lineDef,
1156 W_EXCESS_INITIALIZERS, "scalar",
1159 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1160 list2expr (sym->ival));
1164 setAstLineno (work, sym->lineDef);
1168 init = newNode (NULLOP, init, work);
1177 /*-----------------------------------------------------------------*/
1178 /* freeStringSymbol - delete a literal string if no more usage */
1179 /*-----------------------------------------------------------------*/
1180 void freeStringSymbol(symbol *sym) {
1181 /* make sure this is a literal string */
1182 assert (sym->isstrlit);
1183 if (--sym->isstrlit == 0) { // lower the usage count
1184 memmap *segment=SPEC_OCLS(sym->etype);
1186 deleteSetItem(&segment->syms, sym);
1191 /*-----------------------------------------------------------------*/
1192 /* stringToSymbol - creates a symbol from a literal string */
1193 /*-----------------------------------------------------------------*/
1195 stringToSymbol (value * val)
1197 char name[SDCC_NAME_MAX + 1];
1198 static int charLbl = 0;
1203 // have we heard this before?
1204 for (sp=statsg->syms; sp; sp=sp->next) {
1206 size = getSize (sym->type);
1207 if (sym->isstrlit && size == getSize (val->type) &&
1208 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1209 // yes, this is old news. Don't publish it again.
1210 sym->isstrlit++; // but raise the usage count
1211 return symbolVal(sym);
1215 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1216 sym = newSymbol (name, 0); /* make it @ level 0 */
1217 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1219 /* copy the type from the value passed */
1220 sym->type = copyLinkChain (val->type);
1221 sym->etype = getSpec (sym->type);
1222 /* change to storage class & output class */
1223 SPEC_SCLS (sym->etype) = S_CODE;
1224 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1225 SPEC_STAT (sym->etype) = 1;
1226 /* make the level & block = 0 */
1227 sym->block = sym->level = 0;
1229 /* create an ival */
1230 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1235 allocVariables (sym);
1238 return symbolVal (sym);
1242 /*-----------------------------------------------------------------*/
1243 /* processBlockVars - will go thru the ast looking for block if */
1244 /* a block is found then will allocate the syms */
1245 /* will also gather the auto inits present */
1246 /*-----------------------------------------------------------------*/
1248 processBlockVars (ast * tree, int *stack, int action)
1253 /* if this is a block */
1254 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1258 if (action == ALLOCATE)
1260 *stack += allocVariables (tree->values.sym);
1261 autoInit = gatherAutoInit (tree->values.sym);
1263 /* if there are auto inits then do them */
1265 tree->left = newNode (NULLOP, autoInit, tree->left);
1267 else /* action is deallocate */
1268 deallocLocal (tree->values.sym);
1271 processBlockVars (tree->left, stack, action);
1272 processBlockVars (tree->right, stack, action);
1277 /*-------------------------------------------------------------*/
1278 /* constExprTree - returns TRUE if this tree is a constant */
1280 /*-------------------------------------------------------------*/
1281 bool constExprTree (ast *cexpr) {
1287 cexpr = decorateType (resolveSymbols (cexpr));
1289 switch (cexpr->type)
1292 if (IS_AST_LIT_VALUE(cexpr)) {
1293 // this is a literal
1296 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1297 // a function's address will never change
1300 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1301 // an array's address will never change
1304 if (IS_AST_SYM_VALUE(cexpr) &&
1305 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1306 // a symbol in code space will never change
1307 // This is only for the 'char *s="hallo"' case and will have to leave
1308 //printf(" code space symbol");
1313 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1314 "unexpected link in expression tree\n");
1317 if (cexpr->opval.op==ARRAYINIT) {
1318 // this is a list of literals
1321 if (cexpr->opval.op=='=') {
1322 return constExprTree(cexpr->right);
1324 if (cexpr->opval.op==CAST) {
1325 // cast ignored, maybe we should throw a warning here?
1326 return constExprTree(cexpr->right);
1328 if (cexpr->opval.op=='&') {
1331 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1334 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1339 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1344 /*-----------------------------------------------------------------*/
1345 /* constExprValue - returns the value of a constant expression */
1346 /* or NULL if it is not a constant expression */
1347 /*-----------------------------------------------------------------*/
1349 constExprValue (ast * cexpr, int check)
1351 cexpr = decorateType (resolveSymbols (cexpr));
1353 /* if this is not a constant then */
1354 if (!IS_LITERAL (cexpr->ftype))
1356 /* then check if this is a literal array
1358 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1359 SPEC_CVAL (cexpr->etype).v_char &&
1360 IS_ARRAY (cexpr->ftype))
1362 value *val = valFromType (cexpr->ftype);
1363 SPEC_SCLS (val->etype) = S_LITERAL;
1364 val->sym = cexpr->opval.val->sym;
1365 val->sym->type = copyLinkChain (cexpr->ftype);
1366 val->sym->etype = getSpec (val->sym->type);
1367 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1371 /* if we are casting a literal value then */
1372 if (IS_AST_OP (cexpr) &&
1373 cexpr->opval.op == CAST &&
1374 IS_LITERAL (cexpr->right->ftype))
1376 return valCastLiteral (cexpr->ftype,
1377 floatFromVal (cexpr->right->opval.val));
1380 if (IS_AST_VALUE (cexpr))
1382 return cexpr->opval.val;
1386 werror (E_CONST_EXPECTED, "found expression");
1391 /* return the value */
1392 return cexpr->opval.val;
1396 /*-----------------------------------------------------------------*/
1397 /* isLabelInAst - will return true if a given label is found */
1398 /*-----------------------------------------------------------------*/
1400 isLabelInAst (symbol * label, ast * tree)
1402 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1405 if (IS_AST_OP (tree) &&
1406 tree->opval.op == LABEL &&
1407 isSymbolEqual (AST_SYMBOL (tree->left), label))
1410 return isLabelInAst (label, tree->right) &&
1411 isLabelInAst (label, tree->left);
1415 /*-----------------------------------------------------------------*/
1416 /* isLoopCountable - return true if the loop count can be determi- */
1417 /* -ned at compile time . */
1418 /*-----------------------------------------------------------------*/
1420 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1421 symbol ** sym, ast ** init, ast ** end)
1424 /* the loop is considered countable if the following
1425 conditions are true :-
1427 a) initExpr :- <sym> = <const>
1428 b) condExpr :- <sym> < <const1>
1429 c) loopExpr :- <sym> ++
1432 /* first check the initExpr */
1433 if (IS_AST_OP (initExpr) &&
1434 initExpr->opval.op == '=' && /* is assignment */
1435 IS_AST_SYM_VALUE (initExpr->left))
1436 { /* left is a symbol */
1438 *sym = AST_SYMBOL (initExpr->left);
1439 *init = initExpr->right;
1444 /* for now the symbol has to be of
1446 if (!IS_INTEGRAL ((*sym)->type))
1449 /* now check condExpr */
1450 if (IS_AST_OP (condExpr))
1453 switch (condExpr->opval.op)
1456 if (IS_AST_SYM_VALUE (condExpr->left) &&
1457 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1458 IS_AST_LIT_VALUE (condExpr->right))
1460 *end = condExpr->right;
1466 if (IS_AST_OP (condExpr->left) &&
1467 condExpr->left->opval.op == '>' &&
1468 IS_AST_LIT_VALUE (condExpr->left->right) &&
1469 IS_AST_SYM_VALUE (condExpr->left->left) &&
1470 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1473 *end = newNode ('+', condExpr->left->right,
1474 newAst_VALUE (constVal ("1")));
1485 /* check loop expression is of the form <sym>++ */
1486 if (!IS_AST_OP (loopExpr))
1489 /* check if <sym> ++ */
1490 if (loopExpr->opval.op == INC_OP)
1496 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1497 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1504 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1505 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1513 if (loopExpr->opval.op == ADD_ASSIGN)
1516 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1517 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1518 IS_AST_LIT_VALUE (loopExpr->right) &&
1519 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1527 /*-----------------------------------------------------------------*/
1528 /* astHasVolatile - returns true if ast contains any volatile */
1529 /*-----------------------------------------------------------------*/
1531 astHasVolatile (ast * tree)
1536 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1539 if (IS_AST_OP (tree))
1540 return astHasVolatile (tree->left) ||
1541 astHasVolatile (tree->right);
1546 /*-----------------------------------------------------------------*/
1547 /* astHasPointer - return true if the ast contains any ptr variable */
1548 /*-----------------------------------------------------------------*/
1550 astHasPointer (ast * tree)
1555 if (IS_AST_LINK (tree))
1558 /* if we hit an array expression then check
1559 only the left side */
1560 if (IS_AST_OP (tree) && tree->opval.op == '[')
1561 return astHasPointer (tree->left);
1563 if (IS_AST_VALUE (tree))
1564 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1566 return astHasPointer (tree->left) ||
1567 astHasPointer (tree->right);
1571 /*-----------------------------------------------------------------*/
1572 /* astHasSymbol - return true if the ast has the given symbol */
1573 /*-----------------------------------------------------------------*/
1575 astHasSymbol (ast * tree, symbol * sym)
1577 if (!tree || IS_AST_LINK (tree))
1580 if (IS_AST_VALUE (tree))
1582 if (IS_AST_SYM_VALUE (tree))
1583 return isSymbolEqual (AST_SYMBOL (tree), sym);
1588 return astHasSymbol (tree->left, sym) ||
1589 astHasSymbol (tree->right, sym);
1592 /*-----------------------------------------------------------------*/
1593 /* astHasDeref - return true if the ast has an indirect access */
1594 /*-----------------------------------------------------------------*/
1596 astHasDeref (ast * tree)
1598 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1601 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1603 return astHasDeref (tree->left) || astHasDeref (tree->right);
1606 /*-----------------------------------------------------------------*/
1607 /* isConformingBody - the loop body has to conform to a set of rules */
1608 /* for the loop to be considered reversible read on for rules */
1609 /*-----------------------------------------------------------------*/
1611 isConformingBody (ast * pbody, symbol * sym, ast * body)
1614 /* we are going to do a pre-order traversal of the
1615 tree && check for the following conditions. (essentially
1616 a set of very shallow tests )
1617 a) the sym passed does not participate in
1618 any arithmetic operation
1619 b) There are no function calls
1620 c) all jumps are within the body
1621 d) address of loop control variable not taken
1622 e) if an assignment has a pointer on the
1623 left hand side make sure right does not have
1624 loop control variable */
1626 /* if we reach the end or a leaf then true */
1627 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1630 /* if anything else is "volatile" */
1631 if (IS_VOLATILE (TETYPE (pbody)))
1634 /* we will walk the body in a pre-order traversal for
1636 switch (pbody->opval.op)
1638 /*------------------------------------------------------------------*/
1640 // if the loopvar is used as an index
1641 if (astHasSymbol(pbody->right, sym)) {
1644 return isConformingBody (pbody->right, sym, body);
1646 /*------------------------------------------------------------------*/
1651 /*------------------------------------------------------------------*/
1655 /* sure we are not sym is not modified */
1657 IS_AST_SYM_VALUE (pbody->left) &&
1658 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1662 IS_AST_SYM_VALUE (pbody->right) &&
1663 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1668 /*------------------------------------------------------------------*/
1670 case '*': /* can be unary : if right is null then unary operation */
1675 /* if right is NULL then unary operation */
1676 /*------------------------------------------------------------------*/
1677 /*----------------------------*/
1679 /*----------------------------*/
1682 if (IS_AST_SYM_VALUE (pbody->left) &&
1683 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1686 return isConformingBody (pbody->left, sym, body);
1690 if (astHasSymbol (pbody->left, sym) ||
1691 astHasSymbol (pbody->right, sym))
1696 /*------------------------------------------------------------------*/
1704 if (IS_AST_SYM_VALUE (pbody->left) &&
1705 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1708 if (IS_AST_SYM_VALUE (pbody->right) &&
1709 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1712 return isConformingBody (pbody->left, sym, body) &&
1713 isConformingBody (pbody->right, sym, body);
1721 if (IS_AST_SYM_VALUE (pbody->left) &&
1722 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1724 return isConformingBody (pbody->left, sym, body);
1726 /*------------------------------------------------------------------*/
1738 case SIZEOF: /* evaluate wihout code generation */
1740 if (IS_AST_SYM_VALUE (pbody->left) &&
1741 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1744 if (IS_AST_SYM_VALUE (pbody->right) &&
1745 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1748 return isConformingBody (pbody->left, sym, body) &&
1749 isConformingBody (pbody->right, sym, body);
1751 /*------------------------------------------------------------------*/
1754 /* if left has a pointer & right has loop
1755 control variable then we cannot */
1756 if (astHasPointer (pbody->left) &&
1757 astHasSymbol (pbody->right, sym))
1759 if (astHasVolatile (pbody->left))
1762 if (IS_AST_SYM_VALUE (pbody->left)) {
1763 // if the loopvar has an assignment
1764 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1766 // if the loopvar is used in another (maybe conditional) block
1767 if (astHasSymbol (pbody->right, sym) &&
1768 (pbody->level >= body->level)) {
1773 if (astHasVolatile (pbody->left))
1776 if (astHasDeref(pbody->right)) return FALSE;
1778 return isConformingBody (pbody->left, sym, body) &&
1779 isConformingBody (pbody->right, sym, body);
1790 assert ("Parser should not have generated this\n");
1792 /*------------------------------------------------------------------*/
1793 /*----------------------------*/
1794 /* comma operator */
1795 /*----------------------------*/
1797 return isConformingBody (pbody->left, sym, body) &&
1798 isConformingBody (pbody->right, sym, body);
1800 /*------------------------------------------------------------------*/
1801 /*----------------------------*/
1803 /*----------------------------*/
1805 /* if local & not passed as paramater then ok */
1806 if (sym->level && !astHasSymbol(pbody->right,sym))
1810 /*------------------------------------------------------------------*/
1811 /*----------------------------*/
1812 /* return statement */
1813 /*----------------------------*/
1818 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1823 if (astHasSymbol (pbody->left, sym))
1830 return isConformingBody (pbody->left, sym, body) &&
1831 isConformingBody (pbody->right, sym, body);
1837 /*-----------------------------------------------------------------*/
1838 /* isLoopReversible - takes a for loop as input && returns true */
1839 /* if the for loop is reversible. If yes will set the value of */
1840 /* the loop control var & init value & termination value */
1841 /*-----------------------------------------------------------------*/
1843 isLoopReversible (ast * loop, symbol ** loopCntrl,
1844 ast ** init, ast ** end)
1846 /* if option says don't do it then don't */
1847 if (optimize.noLoopReverse)
1849 /* there are several tests to determine this */
1851 /* for loop has to be of the form
1852 for ( <sym> = <const1> ;
1853 [<sym> < <const2>] ;
1854 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1856 if (!isLoopCountable (AST_FOR (loop, initExpr),
1857 AST_FOR (loop, condExpr),
1858 AST_FOR (loop, loopExpr),
1859 loopCntrl, init, end))
1862 /* now do some serious checking on the body of the loop
1865 return isConformingBody (loop->left, *loopCntrl, loop->left);
1869 /*-----------------------------------------------------------------*/
1870 /* replLoopSym - replace the loop sym by loop sym -1 */
1871 /*-----------------------------------------------------------------*/
1873 replLoopSym (ast * body, symbol * sym)
1876 if (!body || IS_AST_LINK (body))
1879 if (IS_AST_SYM_VALUE (body))
1882 if (isSymbolEqual (AST_SYMBOL (body), sym))
1886 body->opval.op = '-';
1887 body->left = newAst_VALUE (symbolVal (sym));
1888 body->right = newAst_VALUE (constVal ("1"));
1896 replLoopSym (body->left, sym);
1897 replLoopSym (body->right, sym);
1901 /*-----------------------------------------------------------------*/
1902 /* reverseLoop - do the actual loop reversal */
1903 /*-----------------------------------------------------------------*/
1905 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1909 /* create the following tree
1914 if (sym) goto for_continue ;
1917 /* put it together piece by piece */
1918 rloop = newNode (NULLOP,
1919 createIf (newAst_VALUE (symbolVal (sym)),
1921 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1924 newAst_VALUE (symbolVal (sym)),
1927 replLoopSym (loop->left, sym);
1928 setAstLineno (rloop, init->lineno);
1930 rloop = newNode (NULLOP,
1932 newAst_VALUE (symbolVal (sym)),
1933 newNode ('-', end, init)),
1934 createLabel (AST_FOR (loop, continueLabel),
1938 newNode (SUB_ASSIGN,
1939 newAst_VALUE (symbolVal (sym)),
1940 newAst_VALUE (constVal ("1"))),
1943 rloop->lineno=init->lineno;
1944 return decorateType (rloop);
1948 /*-----------------------------------------------------------------*/
1949 /* searchLitOp - search tree (*ops only) for an ast with literal */
1950 /*-----------------------------------------------------------------*/
1952 searchLitOp (ast *tree, ast **parent, const char *ops)
1956 if (tree && optimize.global_cse)
1958 /* is there a literal operand? */
1960 IS_AST_OP(tree->right) &&
1961 tree->right->right &&
1962 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1964 if (IS_LITERAL (RTYPE (tree->right)) ^
1965 IS_LITERAL (LTYPE (tree->right)))
1967 tree->right->decorated = 0;
1968 tree->decorated = 0;
1972 ret = searchLitOp (tree->right, parent, ops);
1977 IS_AST_OP(tree->left) &&
1978 tree->left->right &&
1979 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1981 if (IS_LITERAL (RTYPE (tree->left)) ^
1982 IS_LITERAL (LTYPE (tree->left)))
1984 tree->left->decorated = 0;
1985 tree->decorated = 0;
1989 ret = searchLitOp (tree->left, parent, ops);
1997 /*-----------------------------------------------------------------*/
1998 /* decorateType - compute type for this tree also does type checking */
1999 /* this is done bottom up, since type have to flow upwards */
2000 /* it also does constant folding, and paramater checking */
2001 /*-----------------------------------------------------------------*/
2003 decorateType (ast * tree)
2011 /* if already has type then do nothing */
2012 if (tree->decorated)
2015 tree->decorated = 1;
2018 /* print the line */
2019 /* if not block & function */
2020 if (tree->type == EX_OP &&
2021 (tree->opval.op != FUNCTION &&
2022 tree->opval.op != BLOCK &&
2023 tree->opval.op != NULLOP))
2025 filename = tree->filename;
2026 lineno = tree->lineno;
2030 /* if any child is an error | this one is an error do nothing */
2031 if (tree->isError ||
2032 (tree->left && tree->left->isError) ||
2033 (tree->right && tree->right->isError))
2036 /*------------------------------------------------------------------*/
2037 /*----------------------------*/
2038 /* leaf has been reached */
2039 /*----------------------------*/
2040 lineno=tree->lineno;
2041 /* if this is of type value */
2042 /* just get the type */
2043 if (tree->type == EX_VALUE)
2046 if (IS_LITERAL (tree->opval.val->etype))
2049 /* if this is a character array then declare it */
2050 if (IS_ARRAY (tree->opval.val->type))
2051 tree->opval.val = stringToSymbol (tree->opval.val);
2053 /* otherwise just copy the type information */
2054 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2058 if (tree->opval.val->sym)
2060 /* if the undefined flag is set then give error message */
2061 if (tree->opval.val->sym->undefined)
2063 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2065 TTYPE (tree) = TETYPE (tree) =
2066 tree->opval.val->type = tree->opval.val->sym->type =
2067 tree->opval.val->etype = tree->opval.val->sym->etype =
2068 copyLinkChain (INTTYPE);
2073 /* if impilicit i.e. struct/union member then no type */
2074 if (tree->opval.val->sym->implicit)
2075 TTYPE (tree) = TETYPE (tree) = NULL;
2080 /* else copy the type */
2081 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2083 /* and mark it as referenced */
2084 tree->opval.val->sym->isref = 1;
2092 /* if type link for the case of cast */
2093 if (tree->type == EX_LINK)
2095 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2103 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2105 if (tree->left && tree->left->type == EX_OPERAND
2106 && (tree->left->opval.op == INC_OP
2107 || tree->left->opval.op == DEC_OP)
2108 && tree->left->left)
2110 tree->left->right = tree->left->left;
2111 tree->left->left = NULL;
2113 if (tree->right && tree->right->type == EX_OPERAND
2114 && (tree->right->opval.op == INC_OP
2115 || tree->right->opval.op == DEC_OP)
2116 && tree->right->left)
2118 tree->right->right = tree->right->left;
2119 tree->right->left = NULL;
2124 dtl = decorateType (tree->left);
2125 /* delay right side for '?' operator since conditional macro expansions might
2127 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2129 /* this is to take care of situations
2130 when the tree gets rewritten */
2131 if (dtl != tree->left)
2133 if (dtr != tree->right)
2135 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2138 if (IS_AST_OP(tree) &&
2139 (tree->opval.op == CAST || tree->opval.op == '=') &&
2140 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2141 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2142 // this is a cast/assign to a bigger type
2143 if (IS_AST_OP(tree->right) &&
2144 IS_INTEGRAL(tree->right->ftype) &&
2145 (tree->right->opval.op == LEFT_OP ||
2146 tree->right->opval.op == '*' ||
2147 tree->right->opval.op == '+' ||
2148 tree->right->opval.op == '-') &&
2149 tree->right->right) {
2150 // we should cast an operand instead of the result
2151 tree->right->decorated = 0;
2152 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2154 tree->right = decorateType(tree->right);
2159 /* depending on type of operator do */
2161 switch (tree->opval.op)
2163 /*------------------------------------------------------------------*/
2164 /*----------------------------*/
2166 /*----------------------------*/
2169 /* determine which is the array & which the index */
2170 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2173 ast *tempTree = tree->left;
2174 tree->left = tree->right;
2175 tree->right = tempTree;
2178 /* first check if this is a array or a pointer */
2179 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2181 werror (E_NEED_ARRAY_PTR, "[]");
2182 goto errorTreeReturn;
2185 /* check if the type of the idx */
2186 if (!IS_INTEGRAL (RTYPE (tree)))
2188 werror (E_IDX_NOT_INT);
2189 goto errorTreeReturn;
2192 /* if the left is an rvalue then error */
2195 werror (E_LVALUE_REQUIRED, "array access");
2196 goto errorTreeReturn;
2199 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2202 /*------------------------------------------------------------------*/
2203 /*----------------------------*/
2205 /*----------------------------*/
2207 /* if this is not a structure */
2208 if (!IS_STRUCT (LTYPE (tree)))
2210 werror (E_STRUCT_UNION, ".");
2211 goto errorTreeReturn;
2213 TTYPE (tree) = structElemType (LTYPE (tree),
2214 (tree->right->type == EX_VALUE ?
2215 tree->right->opval.val : NULL));
2216 TETYPE (tree) = getSpec (TTYPE (tree));
2219 /*------------------------------------------------------------------*/
2220 /*----------------------------*/
2221 /* struct/union pointer */
2222 /*----------------------------*/
2224 /* if not pointer to a structure */
2225 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2227 werror (E_PTR_REQD);
2228 goto errorTreeReturn;
2231 if (!IS_STRUCT (LTYPE (tree)->next))
2233 werror (E_STRUCT_UNION, "->");
2234 goto errorTreeReturn;
2237 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2238 (tree->right->type == EX_VALUE ?
2239 tree->right->opval.val : NULL));
2240 TETYPE (tree) = getSpec (TTYPE (tree));
2242 /* adjust the storage class */
2243 switch (DCL_TYPE(tree->left->ftype)) {
2245 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2248 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2251 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2254 SPEC_SCLS (TETYPE (tree)) = 0;
2257 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2260 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2263 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2266 SPEC_SCLS (TETYPE (tree)) = 0;
2273 /* This breaks with extern declarations, bitfields, and perhaps other */
2274 /* cases (gcse). Let's leave this optimization disabled for now and */
2275 /* ponder if there's a safe way to do this. -- EEP */
2277 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2278 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2280 /* If defined struct type at addr var
2281 then rewrite (&struct var)->member
2283 and define membertype at (addr+offsetof(struct var,member)) temp
2286 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2287 AST_SYMBOL(tree->right));
2289 sym = newSymbol(genSymName (0), 0);
2290 sym->type = TTYPE (tree);
2291 sym->etype = getSpec(sym->type);
2292 sym->lineDef = tree->lineno;
2295 SPEC_STAT (sym->etype) = 1;
2296 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2298 SPEC_ABSA(sym->etype) = 1;
2299 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2302 AST_VALUE (tree) = symbolVal(sym);
2305 tree->type = EX_VALUE;
2313 /*------------------------------------------------------------------*/
2314 /*----------------------------*/
2315 /* ++/-- operation */
2316 /*----------------------------*/
2320 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2321 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2322 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2323 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2332 /*------------------------------------------------------------------*/
2333 /*----------------------------*/
2335 /*----------------------------*/
2336 case '&': /* can be unary */
2337 /* if right is NULL then unary operation */
2338 if (tree->right) /* not an unary operation */
2341 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2343 werror (E_BITWISE_OP);
2344 werror (W_CONTINUE, "left & right types are ");
2345 printTypeChain (LTYPE (tree), stderr);
2346 fprintf (stderr, ",");
2347 printTypeChain (RTYPE (tree), stderr);
2348 fprintf (stderr, "\n");
2349 goto errorTreeReturn;
2352 /* if they are both literal */
2353 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2355 tree->type = EX_VALUE;
2356 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2357 valFromType (RETYPE (tree)), '&');
2359 tree->right = tree->left = NULL;
2360 TETYPE (tree) = tree->opval.val->etype;
2361 TTYPE (tree) = tree->opval.val->type;
2365 /* see if this is a GETHBIT operation if yes
2368 ast *otree = optimizeGetHbit (tree);
2371 return decorateType (otree);
2375 computeType (LTYPE (tree), RTYPE (tree));
2376 TETYPE (tree) = getSpec (TTYPE (tree));
2378 /* if left is a literal exchange left & right */
2379 if (IS_LITERAL (LTYPE (tree)))
2381 ast *tTree = tree->left;
2382 tree->left = tree->right;
2383 tree->right = tTree;
2386 /* if right is a literal and */
2387 /* we can find a 2nd literal in a and-tree then */
2388 /* rearrange the tree */
2389 if (IS_LITERAL (RTYPE (tree)))
2392 ast *litTree = searchLitOp (tree, &parent, "&");
2395 ast *tTree = litTree->left;
2396 litTree->left = tree->right;
2397 tree->right = tTree;
2398 /* both operands in tTree are literal now */
2399 decorateType (parent);
2403 LRVAL (tree) = RRVAL (tree) = 1;
2407 /*------------------------------------------------------------------*/
2408 /*----------------------------*/
2410 /*----------------------------*/
2411 p = newLink (DECLARATOR);
2412 /* if bit field then error */
2413 if (IS_BITVAR (tree->left->etype))
2415 werror (E_ILLEGAL_ADDR, "address of bit variable");
2416 goto errorTreeReturn;
2419 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2421 werror (E_ILLEGAL_ADDR, "address of register variable");
2422 goto errorTreeReturn;
2425 if (IS_FUNC (LTYPE (tree)))
2427 // this ought to be ignored
2428 return (tree->left);
2431 if (IS_LITERAL(LTYPE(tree)))
2433 werror (E_ILLEGAL_ADDR, "address of literal");
2434 goto errorTreeReturn;
2439 werror (E_LVALUE_REQUIRED, "address of");
2440 goto errorTreeReturn;
2443 DCL_TYPE (p) = POINTER;
2444 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2445 DCL_TYPE (p) = CPOINTER;
2446 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2447 DCL_TYPE (p) = FPOINTER;
2448 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2449 DCL_TYPE (p) = PPOINTER;
2450 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2451 DCL_TYPE (p) = IPOINTER;
2452 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2453 DCL_TYPE (p) = EEPPOINTER;
2454 else if (SPEC_OCLS(tree->left->etype))
2455 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2457 DCL_TYPE (p) = POINTER;
2459 if (IS_AST_SYM_VALUE (tree->left))
2461 AST_SYMBOL (tree->left)->addrtaken = 1;
2462 AST_SYMBOL (tree->left)->allocreq = 1;
2465 p->next = LTYPE (tree);
2467 TETYPE (tree) = getSpec (TTYPE (tree));
2472 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2473 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2475 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2476 AST_SYMBOL(tree->left->right));
2477 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2478 valueFromLit(element->offset));
2481 tree->type = EX_VALUE;
2482 tree->values.literalFromCast = 1;
2488 /*------------------------------------------------------------------*/
2489 /*----------------------------*/
2491 /*----------------------------*/
2493 /* if the rewrite succeeds then don't go any furthur */
2495 ast *wtree = optimizeRRCRLC (tree);
2497 return decorateType (wtree);
2499 wtree = optimizeSWAP (tree);
2501 return decorateType (wtree);
2506 /* if left is a literal exchange left & right */
2507 if (IS_LITERAL (LTYPE (tree)))
2509 ast *tTree = tree->left;
2510 tree->left = tree->right;
2511 tree->right = tTree;
2514 /* if right is a literal and */
2515 /* we can find a 2nd literal in a or-tree then */
2516 /* rearrange the tree */
2517 if (IS_LITERAL (RTYPE (tree)))
2520 ast *litTree = searchLitOp (tree, &parent, "|");
2523 ast *tTree = litTree->left;
2524 litTree->left = tree->right;
2525 tree->right = tTree;
2526 /* both operands in tTree are literal now */
2527 decorateType (parent);
2530 /*------------------------------------------------------------------*/
2531 /*----------------------------*/
2533 /*----------------------------*/
2535 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2537 werror (E_BITWISE_OP);
2538 werror (W_CONTINUE, "left & right types are ");
2539 printTypeChain (LTYPE (tree), stderr);
2540 fprintf (stderr, ",");
2541 printTypeChain (RTYPE (tree), stderr);
2542 fprintf (stderr, "\n");
2543 goto errorTreeReturn;
2546 /* if they are both literal then */
2547 /* rewrite the tree */
2548 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2550 tree->type = EX_VALUE;
2551 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2552 valFromType (RETYPE (tree)),
2554 tree->right = tree->left = NULL;
2555 TETYPE (tree) = tree->opval.val->etype;
2556 TTYPE (tree) = tree->opval.val->type;
2560 /* if left is a literal exchange left & right */
2561 if (IS_LITERAL (LTYPE (tree)))
2563 ast *tTree = tree->left;
2564 tree->left = tree->right;
2565 tree->right = tTree;
2568 /* if right is a literal and */
2569 /* we can find a 2nd literal in a xor-tree then */
2570 /* rearrange the tree */
2571 if (IS_LITERAL (RTYPE (tree)))
2574 ast *litTree = searchLitOp (tree, &parent, "^");
2577 ast *tTree = litTree->left;
2578 litTree->left = tree->right;
2579 tree->right = tTree;
2580 /* both operands in litTree are literal now */
2581 decorateType (parent);
2585 LRVAL (tree) = RRVAL (tree) = 1;
2586 TETYPE (tree) = getSpec (TTYPE (tree) =
2587 computeType (LTYPE (tree),
2590 /*------------------------------------------------------------------*/
2591 /*----------------------------*/
2593 /*----------------------------*/
2595 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2597 werror (E_INVALID_OP, "divide");
2598 goto errorTreeReturn;
2600 /* if they are both literal then */
2601 /* rewrite the tree */
2602 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2604 tree->type = EX_VALUE;
2605 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2606 valFromType (RETYPE (tree)));
2607 tree->right = tree->left = NULL;
2608 TETYPE (tree) = getSpec (TTYPE (tree) =
2609 tree->opval.val->type);
2613 LRVAL (tree) = RRVAL (tree) = 1;
2614 TETYPE (tree) = getSpec (TTYPE (tree) =
2615 computeType (LTYPE (tree),
2618 /* if right is a literal and */
2619 /* left is also a division by a literal then */
2620 /* rearrange the tree */
2621 if (IS_LITERAL (RTYPE (tree))
2622 /* avoid infinite loop */
2623 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2626 ast *litTree = searchLitOp (tree, &parent, "/");
2629 if (IS_LITERAL (RTYPE (litTree)))
2632 litTree->right = newNode ('*', litTree->right, tree->right);
2633 litTree->right->lineno = tree->lineno;
2635 tree->right->opval.val = constVal ("1");
2636 decorateType (parent);
2640 /* litTree->left is literal: no gcse possible.
2641 We can't call decorateType(parent), because
2642 this would cause an infinit loop. */
2643 parent->decorated = 1;
2644 decorateType (litTree);
2651 /*------------------------------------------------------------------*/
2652 /*----------------------------*/
2654 /*----------------------------*/
2656 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2658 werror (E_BITWISE_OP);
2659 werror (W_CONTINUE, "left & right types are ");
2660 printTypeChain (LTYPE (tree), stderr);
2661 fprintf (stderr, ",");
2662 printTypeChain (RTYPE (tree), stderr);
2663 fprintf (stderr, "\n");
2664 goto errorTreeReturn;
2666 /* if they are both literal then */
2667 /* rewrite the tree */
2668 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2670 tree->type = EX_VALUE;
2671 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2672 valFromType (RETYPE (tree)));
2673 tree->right = tree->left = NULL;
2674 TETYPE (tree) = getSpec (TTYPE (tree) =
2675 tree->opval.val->type);
2678 LRVAL (tree) = RRVAL (tree) = 1;
2679 TETYPE (tree) = getSpec (TTYPE (tree) =
2680 computeType (LTYPE (tree),
2684 /*------------------------------------------------------------------*/
2685 /*----------------------------*/
2686 /* address dereference */
2687 /*----------------------------*/
2688 case '*': /* can be unary : if right is null then unary operation */
2691 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2693 werror (E_PTR_REQD);
2694 goto errorTreeReturn;
2699 werror (E_LVALUE_REQUIRED, "pointer deref");
2700 goto errorTreeReturn;
2702 if (IS_ADDRESS_OF_OP(tree->left))
2704 /* replace *&obj with obj */
2705 return tree->left->left;
2707 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2708 TETYPE (tree) = getSpec (TTYPE (tree));
2709 /* adjust the storage class */
2710 switch (DCL_TYPE(tree->left->ftype)) {
2712 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2715 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2718 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2721 SPEC_SCLS (TETYPE (tree)) = 0;
2724 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2727 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2730 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2733 SPEC_SCLS (TETYPE (tree)) = 0;
2742 /*------------------------------------------------------------------*/
2743 /*----------------------------*/
2744 /* multiplication */
2745 /*----------------------------*/
2746 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2748 werror (E_INVALID_OP, "multiplication");
2749 goto errorTreeReturn;
2752 /* if they are both literal then */
2753 /* rewrite the tree */
2754 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2756 tree->type = EX_VALUE;
2757 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2758 valFromType (RETYPE (tree)));
2759 tree->right = tree->left = NULL;
2760 TETYPE (tree) = getSpec (TTYPE (tree) =
2761 tree->opval.val->type);
2765 /* if left is a literal exchange left & right */
2766 if (IS_LITERAL (LTYPE (tree)))
2768 ast *tTree = tree->left;
2769 tree->left = tree->right;
2770 tree->right = tTree;
2773 /* if right is a literal and */
2774 /* we can find a 2nd literal in a mul-tree then */
2775 /* rearrange the tree */
2776 if (IS_LITERAL (RTYPE (tree)))
2779 ast *litTree = searchLitOp (tree, &parent, "*");
2782 ast *tTree = litTree->left;
2783 litTree->left = tree->right;
2784 tree->right = tTree;
2785 /* both operands in litTree are literal now */
2786 decorateType (parent);
2790 LRVAL (tree) = RRVAL (tree) = 1;
2791 TETYPE (tree) = getSpec (TTYPE (tree) =
2792 computeType (LTYPE (tree),
2795 /* promote result to int if left & right are char
2796 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2797 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2798 SPEC_NOUN(TETYPE(tree)) = V_INT;
2803 /*------------------------------------------------------------------*/
2804 /*----------------------------*/
2805 /* unary '+' operator */
2806 /*----------------------------*/
2811 if (!IS_ARITHMETIC (LTYPE (tree)))
2813 werror (E_UNARY_OP, '+');
2814 goto errorTreeReturn;
2817 /* if left is a literal then do it */
2818 if (IS_LITERAL (LTYPE (tree)))
2820 tree->type = EX_VALUE;
2821 tree->opval.val = valFromType (LETYPE (tree));
2823 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2827 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2831 /*------------------------------------------------------------------*/
2832 /*----------------------------*/
2834 /*----------------------------*/
2836 /* this is not a unary operation */
2837 /* if both pointers then problem */
2838 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2839 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2841 werror (E_PTR_PLUS_PTR);
2842 goto errorTreeReturn;
2845 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2846 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2848 werror (E_PLUS_INVALID, "+");
2849 goto errorTreeReturn;
2852 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2853 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2855 werror (E_PLUS_INVALID, "+");
2856 goto errorTreeReturn;
2858 /* if they are both literal then */
2859 /* rewrite the tree */
2860 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2862 tree->type = EX_VALUE;
2863 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2864 valFromType (RETYPE (tree)));
2865 tree->right = tree->left = NULL;
2866 TETYPE (tree) = getSpec (TTYPE (tree) =
2867 tree->opval.val->type);
2871 /* if the right is a pointer or left is a literal
2872 xchange left & right */
2873 if (IS_ARRAY (RTYPE (tree)) ||
2874 IS_PTR (RTYPE (tree)) ||
2875 IS_LITERAL (LTYPE (tree)))
2877 ast *tTree = tree->left;
2878 tree->left = tree->right;
2879 tree->right = tTree;
2882 /* if right is a literal and */
2883 /* left is also an addition/subtraction with a literal then */
2884 /* rearrange the tree */
2885 if (IS_LITERAL (RTYPE (tree)))
2887 ast *litTree, *parent;
2888 litTree = searchLitOp (tree, &parent, "+-");
2891 if (litTree->opval.op == '+')
2894 ast *tTree = litTree->left;
2895 litTree->left = tree->right;
2896 tree->right = tree->left;
2899 else if (litTree->opval.op == '-')
2901 if (IS_LITERAL (RTYPE (litTree)))
2904 ast *tTree = litTree->left;
2905 litTree->left = tree->right;
2906 tree->right = tTree;
2911 ast *tTree = litTree->right;
2912 litTree->right = tree->right;
2913 tree->right = tTree;
2914 litTree->opval.op = '+';
2915 tree->opval.op = '-';
2918 decorateType (parent);
2922 LRVAL (tree) = RRVAL (tree) = 1;
2923 /* if the left is a pointer */
2924 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2925 TETYPE (tree) = getSpec (TTYPE (tree) =
2928 TETYPE (tree) = getSpec (TTYPE (tree) =
2929 computeType (LTYPE (tree),
2933 /*------------------------------------------------------------------*/
2934 /*----------------------------*/
2936 /*----------------------------*/
2937 case '-': /* can be unary */
2938 /* if right is null then unary */
2942 if (!IS_ARITHMETIC (LTYPE (tree)))
2944 werror (E_UNARY_OP, tree->opval.op);
2945 goto errorTreeReturn;
2948 /* if left is a literal then do it */
2949 if (IS_LITERAL (LTYPE (tree)))
2951 tree->type = EX_VALUE;
2952 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2954 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2955 SPEC_USIGN(TETYPE(tree)) = 0;
2959 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2963 /*------------------------------------------------------------------*/
2964 /*----------------------------*/
2966 /*----------------------------*/
2968 if (!(IS_PTR (LTYPE (tree)) ||
2969 IS_ARRAY (LTYPE (tree)) ||
2970 IS_ARITHMETIC (LTYPE (tree))))
2972 werror (E_PLUS_INVALID, "-");
2973 goto errorTreeReturn;
2976 if (!(IS_PTR (RTYPE (tree)) ||
2977 IS_ARRAY (RTYPE (tree)) ||
2978 IS_ARITHMETIC (RTYPE (tree))))
2980 werror (E_PLUS_INVALID, "-");
2981 goto errorTreeReturn;
2984 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2985 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2986 IS_INTEGRAL (RTYPE (tree))))
2988 werror (E_PLUS_INVALID, "-");
2989 goto errorTreeReturn;
2992 /* if they are both literal then */
2993 /* rewrite the tree */
2994 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2996 tree->type = EX_VALUE;
2997 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2998 valFromType (RETYPE (tree)));
2999 tree->right = tree->left = NULL;
3000 TETYPE (tree) = getSpec (TTYPE (tree) =
3001 tree->opval.val->type);
3005 /* if the left & right are equal then zero */
3006 if (isAstEqual (tree->left, tree->right))
3008 tree->type = EX_VALUE;
3009 tree->left = tree->right = NULL;
3010 tree->opval.val = constVal ("0");
3011 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3015 /* if both of them are pointers or arrays then */
3016 /* the result is going to be an integer */
3017 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3018 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3019 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3021 /* if only the left is a pointer */
3022 /* then result is a pointer */
3023 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3024 TETYPE (tree) = getSpec (TTYPE (tree) =
3027 TETYPE (tree) = getSpec (TTYPE (tree) =
3028 computeType (LTYPE (tree),
3031 LRVAL (tree) = RRVAL (tree) = 1;
3033 /* if right is a literal and */
3034 /* left is also an addition/subtraction with a literal then */
3035 /* rearrange the tree */
3036 if (IS_LITERAL (RTYPE (tree))
3037 /* avoid infinite loop */
3038 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3040 ast *litTree, *litParent;
3041 litTree = searchLitOp (tree, &litParent, "+-");
3044 if (litTree->opval.op == '+')
3047 litTree->right = newNode ('-', litTree->right, tree->right);
3048 litTree->right->lineno = tree->lineno;
3050 tree->right->opval.val = constVal ("0");
3052 else if (litTree->opval.op == '-')
3054 if (IS_LITERAL (RTYPE (litTree)))
3057 litTree->right = newNode ('+', tree->right, litTree->right);
3058 litTree->right->lineno = tree->lineno;
3060 tree->right->opval.val = constVal ("0");
3065 ast *tTree = litTree->right;
3066 litTree->right = tree->right;
3067 tree->right = tTree;
3070 decorateType (litParent);
3075 /*------------------------------------------------------------------*/
3076 /*----------------------------*/
3078 /*----------------------------*/
3080 /* can be only integral type */
3081 if (!IS_INTEGRAL (LTYPE (tree)))
3083 werror (E_UNARY_OP, tree->opval.op);
3084 goto errorTreeReturn;
3087 /* if left is a literal then do it */
3088 if (IS_LITERAL (LTYPE (tree)))
3090 tree->type = EX_VALUE;
3091 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3093 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3097 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3100 /*------------------------------------------------------------------*/
3101 /*----------------------------*/
3103 /*----------------------------*/
3105 /* can be pointer */
3106 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3107 !IS_PTR (LTYPE (tree)) &&
3108 !IS_ARRAY (LTYPE (tree)))
3110 werror (E_UNARY_OP, tree->opval.op);
3111 goto errorTreeReturn;
3114 /* if left is a literal then do it */
3115 if (IS_LITERAL (LTYPE (tree)))
3117 tree->type = EX_VALUE;
3118 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3120 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3124 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3127 /*------------------------------------------------------------------*/
3128 /*----------------------------*/
3130 /*----------------------------*/
3134 TTYPE (tree) = LTYPE (tree);
3135 TETYPE (tree) = LETYPE (tree);
3139 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3144 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3146 werror (E_SHIFT_OP_INVALID);
3147 werror (W_CONTINUE, "left & right types are ");
3148 printTypeChain (LTYPE (tree), stderr);
3149 fprintf (stderr, ",");
3150 printTypeChain (RTYPE (tree), stderr);
3151 fprintf (stderr, "\n");
3152 goto errorTreeReturn;
3155 /* if they are both literal then */
3156 /* rewrite the tree */
3157 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3159 tree->type = EX_VALUE;
3160 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3161 valFromType (RETYPE (tree)),
3162 (tree->opval.op == LEFT_OP ? 1 : 0));
3163 tree->right = tree->left = NULL;
3164 TETYPE (tree) = getSpec (TTYPE (tree) =
3165 tree->opval.val->type);
3169 /* if only the right side is a literal & we are
3170 shifting more than size of the left operand then zero */
3171 if (IS_LITERAL (RTYPE (tree)) &&
3172 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3173 (getSize (LTYPE (tree)) * 8))
3175 if (tree->opval.op==LEFT_OP ||
3176 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3177 lineno=tree->lineno;
3178 werror (W_SHIFT_CHANGED,
3179 (tree->opval.op == LEFT_OP ? "left" : "right"));
3180 tree->type = EX_VALUE;
3181 tree->left = tree->right = NULL;
3182 tree->opval.val = constVal ("0");
3183 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3187 LRVAL (tree) = RRVAL (tree) = 1;
3188 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3189 if (IS_LITERAL (TTYPE (tree)))
3190 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3193 /*------------------------------------------------------------------*/
3194 /*----------------------------*/
3196 /*----------------------------*/
3197 case CAST: /* change the type */
3198 /* cannot cast to an aggregate type */
3199 if (IS_AGGREGATE (LTYPE (tree)))
3201 werror (E_CAST_ILLEGAL);
3202 goto errorTreeReturn;
3205 /* make sure the type is complete and sane */
3206 checkTypeSanity(LETYPE(tree), "(cast)");
3209 /* if the right is a literal replace the tree */
3210 if (IS_LITERAL (RETYPE (tree))) {
3211 if (!IS_PTR (LTYPE (tree))) {
3212 tree->type = EX_VALUE;
3214 valCastLiteral (LTYPE (tree),
3215 floatFromVal (valFromType (RETYPE (tree))));
3218 TTYPE (tree) = tree->opval.val->type;
3219 tree->values.literalFromCast = 1;
3220 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3221 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3222 sym_link *rest = LTYPE(tree)->next;
3223 werror(W_LITERAL_GENERIC);
3224 TTYPE(tree) = newLink(DECLARATOR);
3225 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3226 TTYPE(tree)->next = rest;
3227 tree->left->opval.lnk = TTYPE(tree);
3230 TTYPE (tree) = LTYPE (tree);
3234 TTYPE (tree) = LTYPE (tree);
3238 #if 0 // this is already checked, now this could be explicit
3239 /* if pointer to struct then check names */
3240 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3241 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3242 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3244 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3245 SPEC_STRUCT(LETYPE(tree))->tag);
3248 if (IS_ADDRESS_OF_OP(tree->right)
3249 && IS_AST_SYM_VALUE (tree->right->left)
3250 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3252 tree->type = EX_VALUE;
3254 valCastLiteral (LTYPE (tree),
3255 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3256 TTYPE (tree) = tree->opval.val->type;
3257 TETYPE (tree) = getSpec (TTYPE (tree));
3260 tree->values.literalFromCast = 1;
3264 /* handle offsetof macro: */
3265 /* #define offsetof(TYPE, MEMBER) \ */
3266 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3267 if (IS_ADDRESS_OF_OP(tree->right)
3268 && IS_AST_OP (tree->right->left)
3269 && tree->right->left->opval.op == PTR_OP
3270 && IS_AST_OP (tree->right->left->left)
3271 && tree->right->left->left->opval.op == CAST
3272 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3274 symbol *element = getStructElement (
3275 SPEC_STRUCT (LETYPE(tree->right->left)),
3276 AST_SYMBOL(tree->right->left->right)
3280 tree->type = EX_VALUE;
3281 tree->opval.val = valCastLiteral (
3284 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3287 TTYPE (tree) = tree->opval.val->type;
3288 TETYPE (tree) = getSpec (TTYPE (tree));
3295 /* if the right is a literal replace the tree */
3296 if (IS_LITERAL (RETYPE (tree))) {
3297 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3298 /* rewrite (type *)litaddr
3300 and define type at litaddr temp
3301 (but only if type's storage class is not generic)
3303 ast *newTree = newNode ('&', NULL, NULL);
3306 TTYPE (newTree) = LTYPE (tree);
3307 TETYPE (newTree) = getSpec(LTYPE (tree));
3309 /* define a global symbol at the casted address*/
3310 sym = newSymbol(genSymName (0), 0);
3311 sym->type = LTYPE (tree)->next;
3313 sym->type = newLink (V_VOID);
3314 sym->etype = getSpec(sym->type);
3315 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3316 sym->lineDef = tree->lineno;
3319 SPEC_STAT (sym->etype) = 1;
3320 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3321 SPEC_ABSA(sym->etype) = 1;
3322 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3325 newTree->left = newAst_VALUE(symbolVal(sym));
3326 newTree->left->lineno = tree->lineno;
3327 LTYPE (newTree) = sym->type;
3328 LETYPE (newTree) = sym->etype;
3329 LLVAL (newTree) = 1;
3330 LRVAL (newTree) = 0;
3331 TLVAL (newTree) = 1;
3334 if (!IS_PTR (LTYPE (tree))) {
3335 tree->type = EX_VALUE;
3337 valCastLiteral (LTYPE (tree),
3338 floatFromVal (valFromType (RTYPE (tree))));
3339 TTYPE (tree) = tree->opval.val->type;
3342 tree->values.literalFromCast = 1;
3343 TETYPE (tree) = getSpec (TTYPE (tree));
3347 TTYPE (tree) = LTYPE (tree);
3351 TETYPE (tree) = getSpec (TTYPE (tree));
3355 /*------------------------------------------------------------------*/
3356 /*----------------------------*/
3357 /* logical &&, || */
3358 /*----------------------------*/
3361 /* each must me arithmetic type or be a pointer */
3362 if (!IS_PTR (LTYPE (tree)) &&
3363 !IS_ARRAY (LTYPE (tree)) &&
3364 !IS_INTEGRAL (LTYPE (tree)))
3366 werror (E_COMPARE_OP);
3367 goto errorTreeReturn;
3370 if (!IS_PTR (RTYPE (tree)) &&
3371 !IS_ARRAY (RTYPE (tree)) &&
3372 !IS_INTEGRAL (RTYPE (tree)))
3374 werror (E_COMPARE_OP);
3375 goto errorTreeReturn;
3377 /* if they are both literal then */
3378 /* rewrite the tree */
3379 if (IS_LITERAL (RTYPE (tree)) &&
3380 IS_LITERAL (LTYPE (tree)))
3382 tree->type = EX_VALUE;
3383 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3384 valFromType (RTYPE (tree)),
3386 tree->right = tree->left = NULL;
3387 TETYPE (tree) = getSpec (TTYPE (tree) =
3388 tree->opval.val->type);
3391 LRVAL (tree) = RRVAL (tree) = 1;
3392 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3395 /*------------------------------------------------------------------*/
3396 /*----------------------------*/
3397 /* comparison operators */
3398 /*----------------------------*/
3406 ast *lt = optimizeCompare (tree);
3412 /* if they are pointers they must be castable */
3413 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3415 if (tree->opval.op==EQ_OP &&
3416 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3417 // we cannot cast a gptr to a !gptr: switch the leaves
3418 struct ast *s=tree->left;
3419 tree->left=tree->right;
3422 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3424 werror (E_COMPARE_OP);
3425 fprintf (stderr, "comparing type ");
3426 printTypeChain (LTYPE (tree), stderr);
3427 fprintf (stderr, "to type ");
3428 printTypeChain (RTYPE (tree), stderr);
3429 fprintf (stderr, "\n");
3430 goto errorTreeReturn;
3433 /* else they should be promotable to one another */
3436 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3437 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3439 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3441 werror (E_COMPARE_OP);
3442 fprintf (stderr, "comparing type ");
3443 printTypeChain (LTYPE (tree), stderr);
3444 fprintf (stderr, "to type ");
3445 printTypeChain (RTYPE (tree), stderr);
3446 fprintf (stderr, "\n");
3447 goto errorTreeReturn;
3450 /* if unsigned value < 0 then always false */
3451 /* if (unsigned value) > 0 then (unsigned value) */
3452 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3453 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3455 if (tree->opval.op == '<') {
3458 if (tree->opval.op == '>') {
3462 /* if they are both literal then */
3463 /* rewrite the tree */
3464 if (IS_LITERAL (RTYPE (tree)) &&
3465 IS_LITERAL (LTYPE (tree)))
3467 tree->type = EX_VALUE;
3468 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3469 valFromType (RETYPE (tree)),
3471 tree->right = tree->left = NULL;
3472 TETYPE (tree) = getSpec (TTYPE (tree) =
3473 tree->opval.val->type);
3476 LRVAL (tree) = RRVAL (tree) = 1;
3477 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3480 /*------------------------------------------------------------------*/
3481 /*----------------------------*/
3483 /*----------------------------*/
3484 case SIZEOF: /* evaluate wihout code generation */
3485 /* change the type to a integer */
3486 tree->type = EX_VALUE;
3487 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3488 tree->opval.val = constVal (buffer);
3489 tree->right = tree->left = NULL;
3490 TETYPE (tree) = getSpec (TTYPE (tree) =
3491 tree->opval.val->type);
3494 /*------------------------------------------------------------------*/
3495 /*----------------------------*/
3497 /*----------------------------*/
3499 /* return typeof enum value */
3500 tree->type = EX_VALUE;
3503 if (IS_SPEC(tree->right->ftype)) {
3504 switch (SPEC_NOUN(tree->right->ftype)) {
3506 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3507 else typeofv = TYPEOF_INT;
3510 typeofv = TYPEOF_FLOAT;
3513 typeofv = TYPEOF_CHAR;
3516 typeofv = TYPEOF_VOID;
3519 typeofv = TYPEOF_STRUCT;
3522 typeofv = TYPEOF_BITFIELD;
3525 typeofv = TYPEOF_BIT;
3528 typeofv = TYPEOF_SBIT;
3534 switch (DCL_TYPE(tree->right->ftype)) {
3536 typeofv = TYPEOF_POINTER;
3539 typeofv = TYPEOF_FPOINTER;
3542 typeofv = TYPEOF_CPOINTER;
3545 typeofv = TYPEOF_GPOINTER;
3548 typeofv = TYPEOF_PPOINTER;
3551 typeofv = TYPEOF_IPOINTER;
3554 typeofv = TYPEOF_ARRAY;
3557 typeofv = TYPEOF_FUNCTION;
3563 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3564 tree->opval.val = constVal (buffer);
3565 tree->right = tree->left = NULL;
3566 TETYPE (tree) = getSpec (TTYPE (tree) =
3567 tree->opval.val->type);
3570 /*------------------------------------------------------------------*/
3571 /*----------------------------*/
3572 /* conditional operator '?' */
3573 /*----------------------------*/
3575 /* the type is value of the colon operator (on the right) */
3576 assert(IS_COLON_OP(tree->right));
3577 /* if already known then replace the tree : optimizer will do it
3578 but faster to do it here */
3579 if (IS_LITERAL (LTYPE(tree))) {
3580 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3581 return decorateType(tree->right->left) ;
3583 return decorateType(tree->right->right) ;
3586 tree->right = decorateType(tree->right);
3587 TTYPE (tree) = RTYPE(tree);
3588 TETYPE (tree) = getSpec (TTYPE (tree));
3593 /* if they don't match we have a problem */
3594 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3596 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3597 goto errorTreeReturn;
3600 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3601 TETYPE (tree) = getSpec (TTYPE (tree));
3605 #if 0 // assignment operators are converted by the parser
3606 /*------------------------------------------------------------------*/
3607 /*----------------------------*/
3608 /* assignment operators */
3609 /*----------------------------*/
3612 /* for these it must be both must be integral */
3613 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3614 !IS_ARITHMETIC (RTYPE (tree)))
3616 werror (E_OPS_INTEGRAL);
3617 goto errorTreeReturn;
3620 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3622 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3623 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3627 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3628 goto errorTreeReturn;
3639 /* for these it must be both must be integral */
3640 if (!IS_INTEGRAL (LTYPE (tree)) ||
3641 !IS_INTEGRAL (RTYPE (tree)))
3643 werror (E_OPS_INTEGRAL);
3644 goto errorTreeReturn;
3647 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3649 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3650 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3654 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3655 goto errorTreeReturn;
3661 /*------------------------------------------------------------------*/
3662 /*----------------------------*/
3664 /*----------------------------*/
3666 if (!(IS_PTR (LTYPE (tree)) ||
3667 IS_ARITHMETIC (LTYPE (tree))))
3669 werror (E_PLUS_INVALID, "-=");
3670 goto errorTreeReturn;
3673 if (!(IS_PTR (RTYPE (tree)) ||
3674 IS_ARITHMETIC (RTYPE (tree))))
3676 werror (E_PLUS_INVALID, "-=");
3677 goto errorTreeReturn;
3680 TETYPE (tree) = getSpec (TTYPE (tree) =
3681 computeType (LTYPE (tree),
3684 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3685 werror (E_CODE_WRITE, "-=");
3689 werror (E_LVALUE_REQUIRED, "-=");
3690 goto errorTreeReturn;
3696 /*------------------------------------------------------------------*/
3697 /*----------------------------*/
3699 /*----------------------------*/
3701 /* this is not a unary operation */
3702 /* if both pointers then problem */
3703 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3705 werror (E_PTR_PLUS_PTR);
3706 goto errorTreeReturn;
3709 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3711 werror (E_PLUS_INVALID, "+=");
3712 goto errorTreeReturn;
3715 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3717 werror (E_PLUS_INVALID, "+=");
3718 goto errorTreeReturn;
3721 TETYPE (tree) = getSpec (TTYPE (tree) =
3722 computeType (LTYPE (tree),
3725 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3726 werror (E_CODE_WRITE, "+=");
3730 werror (E_LVALUE_REQUIRED, "+=");
3731 goto errorTreeReturn;
3734 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3735 tree->opval.op = '=';
3740 /*------------------------------------------------------------------*/
3741 /*----------------------------*/
3742 /* straight assignemnt */
3743 /*----------------------------*/
3745 /* cannot be an aggregate */
3746 if (IS_AGGREGATE (LTYPE (tree)))
3748 werror (E_AGGR_ASSIGN);
3749 goto errorTreeReturn;
3752 /* they should either match or be castable */
3753 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3755 werror (E_TYPE_MISMATCH, "assignment", " ");
3756 printFromToType(RTYPE(tree),LTYPE(tree));
3759 /* if the left side of the tree is of type void
3760 then report error */
3761 if (IS_VOID (LTYPE (tree)))
3763 werror (E_CAST_ZERO);
3764 printFromToType(RTYPE(tree), LTYPE(tree));
3767 TETYPE (tree) = getSpec (TTYPE (tree) =
3771 if (!tree->initMode ) {
3772 if (IS_CONSTANT(LTYPE(tree)))
3773 werror (E_CODE_WRITE, "=");
3777 werror (E_LVALUE_REQUIRED, "=");
3778 goto errorTreeReturn;
3783 /*------------------------------------------------------------------*/
3784 /*----------------------------*/
3785 /* comma operator */
3786 /*----------------------------*/
3788 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3791 /*------------------------------------------------------------------*/
3792 /*----------------------------*/
3794 /*----------------------------*/
3798 if (processParms (tree->left,
3799 FUNC_ARGS(tree->left->ftype),
3800 tree->right, &parmNumber, TRUE)) {
3801 goto errorTreeReturn;
3804 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3805 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3807 reverseParms (tree->right);
3810 if (IS_CODEPTR(LTYPE(tree))) {
3811 TTYPE(tree) = LTYPE(tree)->next->next;
3813 TTYPE(tree) = LTYPE(tree)->next;
3815 TETYPE (tree) = getSpec (TTYPE (tree));
3818 /*------------------------------------------------------------------*/
3819 /*----------------------------*/
3820 /* return statement */
3821 /*----------------------------*/
3826 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3828 werror (W_RETURN_MISMATCH);
3829 printFromToType (RTYPE(tree), currFunc->type->next);
3830 goto errorTreeReturn;
3833 if (IS_VOID (currFunc->type->next)
3835 !IS_VOID (RTYPE (tree)))
3837 werror (E_FUNC_VOID);
3838 goto errorTreeReturn;
3841 /* if there is going to be a casing required then add it */
3842 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3845 decorateType (newNode (CAST,
3846 newAst_LINK (copyLinkChain (currFunc->type->next)),
3855 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3857 werror (W_VOID_FUNC, currFunc->name);
3858 goto errorTreeReturn;
3861 TTYPE (tree) = TETYPE (tree) = NULL;
3864 /*------------------------------------------------------------------*/
3865 /*----------------------------*/
3866 /* switch statement */
3867 /*----------------------------*/
3869 /* the switch value must be an integer */
3870 if (!IS_INTEGRAL (LTYPE (tree)))
3872 werror (E_SWITCH_NON_INTEGER);
3873 goto errorTreeReturn;
3876 TTYPE (tree) = TETYPE (tree) = NULL;
3879 /*------------------------------------------------------------------*/
3880 /*----------------------------*/
3882 /*----------------------------*/
3884 tree->left = backPatchLabels (tree->left,
3887 TTYPE (tree) = TETYPE (tree) = NULL;
3890 /*------------------------------------------------------------------*/
3891 /*----------------------------*/
3893 /*----------------------------*/
3896 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3897 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3898 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3900 /* if the for loop is reversible then
3901 reverse it otherwise do what we normally
3907 if (isLoopReversible (tree, &sym, &init, &end))
3908 return reverseLoop (tree, sym, init, end);
3910 return decorateType (createFor (AST_FOR (tree, trueLabel),
3911 AST_FOR (tree, continueLabel),
3912 AST_FOR (tree, falseLabel),
3913 AST_FOR (tree, condLabel),
3914 AST_FOR (tree, initExpr),
3915 AST_FOR (tree, condExpr),
3916 AST_FOR (tree, loopExpr),
3920 TTYPE (tree) = TETYPE (tree) = NULL;
3924 /* some error found this tree will be killed */
3926 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3927 tree->opval.op = NULLOP;
3933 /*-----------------------------------------------------------------*/
3934 /* sizeofOp - processes size of operation */
3935 /*-----------------------------------------------------------------*/
3937 sizeofOp (sym_link * type)
3941 /* make sure the type is complete and sane */
3942 checkTypeSanity(type, "(sizeof)");
3944 /* get the size and convert it to character */
3945 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3947 /* now convert into value */
3948 return constVal (buff);
3952 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3953 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3954 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3955 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3956 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3957 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3958 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3960 /*-----------------------------------------------------------------*/
3961 /* backPatchLabels - change and or not operators to flow control */
3962 /*-----------------------------------------------------------------*/
3964 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3970 if (!(IS_ANDORNOT (tree)))
3973 /* if this an and */
3976 static int localLbl = 0;
3979 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3980 localLabel = newSymbol (buffer, NestLevel);
3982 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3984 /* if left is already a IFX then just change the if true label in that */
3985 if (!IS_IFX (tree->left))
3986 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3988 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3989 /* right is a IFX then just join */
3990 if (IS_IFX (tree->right))
3991 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3993 tree->right = createLabel (localLabel, tree->right);
3994 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3996 return newNode (NULLOP, tree->left, tree->right);
3999 /* if this is an or operation */
4002 static int localLbl = 0;
4005 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4006 localLabel = newSymbol (buffer, NestLevel);
4008 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4010 /* if left is already a IFX then just change the if true label in that */
4011 if (!IS_IFX (tree->left))
4012 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4014 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4015 /* right is a IFX then just join */
4016 if (IS_IFX (tree->right))
4017 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4019 tree->right = createLabel (localLabel, tree->right);
4020 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4022 return newNode (NULLOP, tree->left, tree->right);
4028 int wasnot = IS_NOT (tree->left);
4029 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4031 /* if the left is already a IFX */
4032 if (!IS_IFX (tree->left))
4033 tree->left = newNode (IFX, tree->left, NULL);
4037 tree->left->trueLabel = trueLabel;
4038 tree->left->falseLabel = falseLabel;
4042 tree->left->trueLabel = falseLabel;
4043 tree->left->falseLabel = trueLabel;
4050 tree->trueLabel = trueLabel;
4051 tree->falseLabel = falseLabel;
4058 /*-----------------------------------------------------------------*/
4059 /* createBlock - create expression tree for block */
4060 /*-----------------------------------------------------------------*/
4062 createBlock (symbol * decl, ast * body)
4066 /* if the block has nothing */
4070 ex = newNode (BLOCK, NULL, body);
4071 ex->values.sym = decl;
4073 ex->right = ex->right;
4079 /*-----------------------------------------------------------------*/
4080 /* createLabel - creates the expression tree for labels */
4081 /*-----------------------------------------------------------------*/
4083 createLabel (symbol * label, ast * stmnt)
4086 char name[SDCC_NAME_MAX + 1];
4089 /* must create fresh symbol if the symbol name */
4090 /* exists in the symbol table, since there can */
4091 /* be a variable with the same name as the labl */
4092 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4093 (csym->level == label->level))
4094 label = newSymbol (label->name, label->level);
4096 /* change the name before putting it in add _ */
4097 SNPRINTF(name, sizeof(name), "%s", label->name);
4099 /* put the label in the LabelSymbol table */
4100 /* but first check if a label of the same */
4102 if ((csym = findSym (LabelTab, NULL, name)))
4103 werror (E_DUPLICATE_LABEL, label->name);
4105 addSym (LabelTab, label, name, label->level, 0, 0);
4108 label->key = labelKey++;
4109 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4115 /*-----------------------------------------------------------------*/
4116 /* createCase - generates the parsetree for a case statement */
4117 /*-----------------------------------------------------------------*/
4119 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4121 char caseLbl[SDCC_NAME_MAX + 1];
4125 /* if the switch statement does not exist */
4126 /* then case is out of context */
4129 werror (E_CASE_CONTEXT);
4133 caseVal = decorateType (resolveSymbols (caseVal));
4134 /* if not a constant then error */
4135 if (!IS_LITERAL (caseVal->ftype))
4137 werror (E_CASE_CONSTANT);
4141 /* if not a integer than error */
4142 if (!IS_INTEGRAL (caseVal->ftype))
4144 werror (E_CASE_NON_INTEGER);
4148 /* find the end of the switch values chain */
4149 if (!(val = swStat->values.switchVals.swVals))
4150 swStat->values.switchVals.swVals = caseVal->opval.val;
4153 /* also order the cases according to value */
4155 int cVal = (int) floatFromVal (caseVal->opval.val);
4156 while (val && (int) floatFromVal (val) < cVal)
4162 /* if we reached the end then */
4165 pval->next = caseVal->opval.val;
4169 /* we found a value greater than */
4170 /* the current value we must add this */
4171 /* before the value */
4172 caseVal->opval.val->next = val;
4174 /* if this was the first in chain */
4175 if (swStat->values.switchVals.swVals == val)
4176 swStat->values.switchVals.swVals =
4179 pval->next = caseVal->opval.val;
4184 /* create the case label */
4185 SNPRINTF(caseLbl, sizeof(caseLbl),
4187 swStat->values.switchVals.swNum,
4188 (int) floatFromVal (caseVal->opval.val));
4190 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4195 /*-----------------------------------------------------------------*/
4196 /* createDefault - creates the parse tree for the default statement */
4197 /*-----------------------------------------------------------------*/
4199 createDefault (ast * swStat, ast * stmnt)
4201 char defLbl[SDCC_NAME_MAX + 1];
4203 /* if the switch statement does not exist */
4204 /* then case is out of context */
4207 werror (E_CASE_CONTEXT);
4211 /* turn on the default flag */
4212 swStat->values.switchVals.swDefault = 1;
4214 /* create the label */
4215 SNPRINTF (defLbl, sizeof(defLbl),
4216 "_default_%d", swStat->values.switchVals.swNum);
4217 return createLabel (newSymbol (defLbl, 0), stmnt);
4220 /*-----------------------------------------------------------------*/
4221 /* createIf - creates the parsetree for the if statement */
4222 /*-----------------------------------------------------------------*/
4224 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4226 static int Lblnum = 0;
4228 symbol *ifTrue, *ifFalse, *ifEnd;
4230 /* if neither exists */
4231 if (!elseBody && !ifBody) {
4232 // if there are no side effects (i++, j() etc)
4233 if (!hasSEFcalls(condAst)) {
4238 /* create the labels */
4239 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4240 ifFalse = newSymbol (buffer, NestLevel);
4241 /* if no else body then end == false */
4246 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4247 ifEnd = newSymbol (buffer, NestLevel);
4250 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4251 ifTrue = newSymbol (buffer, NestLevel);
4255 /* attach the ifTrue label to the top of it body */
4256 ifBody = createLabel (ifTrue, ifBody);
4257 /* attach a goto end to the ifBody if else is present */
4260 ifBody = newNode (NULLOP, ifBody,
4262 newAst_VALUE (symbolVal (ifEnd)),
4264 /* put the elseLabel on the else body */
4265 elseBody = createLabel (ifFalse, elseBody);
4266 /* out the end at the end of the body */
4267 elseBody = newNode (NULLOP,
4269 createLabel (ifEnd, NULL));
4273 ifBody = newNode (NULLOP, ifBody,
4274 createLabel (ifFalse, NULL));
4276 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4277 if (IS_IFX (condAst))
4280 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4282 return newNode (NULLOP, ifTree,
4283 newNode (NULLOP, ifBody, elseBody));
4287 /*-----------------------------------------------------------------*/
4288 /* createDo - creates parse tree for do */
4291 /* _docontinue_n: */
4292 /* condition_expression +-> trueLabel -> _dobody_n */
4294 /* +-> falseLabel-> _dobreak_n */
4296 /*-----------------------------------------------------------------*/
4298 createDo (symbol * trueLabel, symbol * continueLabel,
4299 symbol * falseLabel, ast * condAst, ast * doBody)
4304 /* if the body does not exist then it is simple */
4307 condAst = backPatchLabels (condAst, continueLabel, NULL);
4308 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4309 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4310 doTree->trueLabel = continueLabel;
4311 doTree->falseLabel = NULL;
4315 /* otherwise we have a body */
4316 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4318 /* attach the body label to the top */
4319 doBody = createLabel (trueLabel, doBody);
4320 /* attach the continue label to end of body */
4321 doBody = newNode (NULLOP, doBody,
4322 createLabel (continueLabel, NULL));
4324 /* now put the break label at the end */
4325 if (IS_IFX (condAst))
4328 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4330 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4332 /* putting it together */
4333 return newNode (NULLOP, doBody, doTree);
4336 /*-----------------------------------------------------------------*/
4337 /* createFor - creates parse tree for 'for' statement */
4340 /* condExpr +-> trueLabel -> _forbody_n */
4342 /* +-> falseLabel-> _forbreak_n */
4345 /* _forcontinue_n: */
4347 /* goto _forcond_n ; */
4349 /*-----------------------------------------------------------------*/
4351 createFor (symbol * trueLabel, symbol * continueLabel,
4352 symbol * falseLabel, symbol * condLabel,
4353 ast * initExpr, ast * condExpr, ast * loopExpr,
4358 /* if loopexpression not present then we can generate it */
4359 /* the same way as a while */
4361 return newNode (NULLOP, initExpr,
4362 createWhile (trueLabel, continueLabel,
4363 falseLabel, condExpr, forBody));
4364 /* vanilla for statement */
4365 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4367 if (condExpr && !IS_IFX (condExpr))
4368 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4371 /* attach condition label to condition */
4372 condExpr = createLabel (condLabel, condExpr);
4374 /* attach body label to body */
4375 forBody = createLabel (trueLabel, forBody);
4377 /* attach continue to forLoop expression & attach */
4378 /* goto the forcond @ and of loopExpression */
4379 loopExpr = createLabel (continueLabel,
4383 newAst_VALUE (symbolVal (condLabel)),
4385 /* now start putting them together */
4386 forTree = newNode (NULLOP, initExpr, condExpr);
4387 forTree = newNode (NULLOP, forTree, forBody);
4388 forTree = newNode (NULLOP, forTree, loopExpr);
4389 /* finally add the break label */
4390 forTree = newNode (NULLOP, forTree,
4391 createLabel (falseLabel, NULL));
4395 /*-----------------------------------------------------------------*/
4396 /* createWhile - creates parse tree for while statement */
4397 /* the while statement will be created as follows */
4399 /* _while_continue_n: */
4400 /* condition_expression +-> trueLabel -> _while_boby_n */
4402 /* +-> falseLabel -> _while_break_n */
4403 /* _while_body_n: */
4405 /* goto _while_continue_n */
4406 /* _while_break_n: */
4407 /*-----------------------------------------------------------------*/
4409 createWhile (symbol * trueLabel, symbol * continueLabel,
4410 symbol * falseLabel, ast * condExpr, ast * whileBody)
4414 /* put the continue label */
4415 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4416 condExpr = createLabel (continueLabel, condExpr);
4417 condExpr->lineno = 0;
4419 /* put the body label in front of the body */
4420 whileBody = createLabel (trueLabel, whileBody);
4421 whileBody->lineno = 0;
4422 /* put a jump to continue at the end of the body */
4423 /* and put break label at the end of the body */
4424 whileBody = newNode (NULLOP,
4427 newAst_VALUE (symbolVal (continueLabel)),
4428 createLabel (falseLabel, NULL)));
4430 /* put it all together */
4431 if (IS_IFX (condExpr))
4432 whileTree = condExpr;
4435 whileTree = newNode (IFX, condExpr, NULL);
4436 /* put the true & false labels in place */
4437 whileTree->trueLabel = trueLabel;
4438 whileTree->falseLabel = falseLabel;
4441 return newNode (NULLOP, whileTree, whileBody);
4444 /*-----------------------------------------------------------------*/
4445 /* optimizeGetHbit - get highest order bit of the expression */
4446 /*-----------------------------------------------------------------*/
4448 optimizeGetHbit (ast * tree)
4451 /* if this is not a bit and */
4452 if (!IS_BITAND (tree))
4455 /* will look for tree of the form
4456 ( expr >> ((sizeof expr) -1) ) & 1 */
4457 if (!IS_AST_LIT_VALUE (tree->right))
4460 if (AST_LIT_VALUE (tree->right) != 1)
4463 if (!IS_RIGHT_OP (tree->left))
4466 if (!IS_AST_LIT_VALUE (tree->left->right))
4469 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4470 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4473 /* make sure the port supports GETHBIT */
4474 if (port->hasExtBitOp
4475 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4478 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4482 /*-----------------------------------------------------------------*/
4483 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4484 /*-----------------------------------------------------------------*/
4486 optimizeRRCRLC (ast * root)
4488 /* will look for trees of the form
4489 (?expr << 1) | (?expr >> 7) or
4490 (?expr >> 7) | (?expr << 1) will make that
4491 into a RLC : operation ..
4493 (?expr >> 1) | (?expr << 7) or
4494 (?expr << 7) | (?expr >> 1) will make that
4495 into a RRC operation
4496 note : by 7 I mean (number of bits required to hold the
4498 /* if the root operations is not a | operation the not */
4499 if (!IS_BITOR (root))
4502 /* I have to think of a better way to match patterns this sucks */
4503 /* that aside let start looking for the first case : I use a the
4504 negative check a lot to improve the efficiency */
4505 /* (?expr << 1) | (?expr >> 7) */
4506 if (IS_LEFT_OP (root->left) &&
4507 IS_RIGHT_OP (root->right))
4510 if (!SPEC_USIGN (TETYPE (root->left->left)))
4513 if (!IS_AST_LIT_VALUE (root->left->right) ||
4514 !IS_AST_LIT_VALUE (root->right->right))
4517 /* make sure it is the same expression */
4518 if (!isAstEqual (root->left->left,
4522 if (AST_LIT_VALUE (root->left->right) != 1)
4525 if (AST_LIT_VALUE (root->right->right) !=
4526 (getSize (TTYPE (root->left->left)) * 8 - 1))
4529 /* make sure the port supports RLC */
4530 if (port->hasExtBitOp
4531 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4534 /* whew got the first case : create the AST */
4535 return newNode (RLC, root->left->left, NULL);
4539 /* check for second case */
4540 /* (?expr >> 7) | (?expr << 1) */
4541 if (IS_LEFT_OP (root->right) &&
4542 IS_RIGHT_OP (root->left))
4545 if (!SPEC_USIGN (TETYPE (root->left->left)))
4548 if (!IS_AST_LIT_VALUE (root->left->right) ||
4549 !IS_AST_LIT_VALUE (root->right->right))
4552 /* make sure it is the same symbol */
4553 if (!isAstEqual (root->left->left,
4557 if (AST_LIT_VALUE (root->right->right) != 1)
4560 if (AST_LIT_VALUE (root->left->right) !=
4561 (getSize (TTYPE (root->left->left)) * 8 - 1))
4564 /* make sure the port supports RLC */
4565 if (port->hasExtBitOp
4566 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4569 /* whew got the first case : create the AST */
4570 return newNode (RLC, root->left->left, NULL);
4575 /* third case for RRC */
4576 /* (?symbol >> 1) | (?symbol << 7) */
4577 if (IS_LEFT_OP (root->right) &&
4578 IS_RIGHT_OP (root->left))
4581 if (!SPEC_USIGN (TETYPE (root->left->left)))
4584 if (!IS_AST_LIT_VALUE (root->left->right) ||
4585 !IS_AST_LIT_VALUE (root->right->right))
4588 /* make sure it is the same symbol */
4589 if (!isAstEqual (root->left->left,
4593 if (AST_LIT_VALUE (root->left->right) != 1)
4596 if (AST_LIT_VALUE (root->right->right) !=
4597 (getSize (TTYPE (root->left->left)) * 8 - 1))
4600 /* make sure the port supports RRC */
4601 if (port->hasExtBitOp
4602 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4605 /* whew got the first case : create the AST */
4606 return newNode (RRC, root->left->left, NULL);
4610 /* fourth and last case for now */
4611 /* (?symbol << 7) | (?symbol >> 1) */
4612 if (IS_RIGHT_OP (root->right) &&
4613 IS_LEFT_OP (root->left))
4616 if (!SPEC_USIGN (TETYPE (root->left->left)))
4619 if (!IS_AST_LIT_VALUE (root->left->right) ||
4620 !IS_AST_LIT_VALUE (root->right->right))
4623 /* make sure it is the same symbol */
4624 if (!isAstEqual (root->left->left,
4628 if (AST_LIT_VALUE (root->right->right) != 1)
4631 if (AST_LIT_VALUE (root->left->right) !=
4632 (getSize (TTYPE (root->left->left)) * 8 - 1))
4635 /* make sure the port supports RRC */
4636 if (port->hasExtBitOp
4637 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4640 /* whew got the first case : create the AST */
4641 return newNode (RRC, root->left->left, NULL);
4645 /* not found return root */
4649 /*-----------------------------------------------------------------*/
4650 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4651 /*-----------------------------------------------------------------*/
4653 optimizeSWAP (ast * root)
4655 /* will look for trees of the form
4656 (?expr << 4) | (?expr >> 4) or
4657 (?expr >> 4) | (?expr << 4) will make that
4658 into a SWAP : operation ..
4659 note : by 4 I mean (number of bits required to hold the
4661 /* if the root operations is not a | operation the not */
4662 if (!IS_BITOR (root))
4665 /* (?expr << 4) | (?expr >> 4) */
4666 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4667 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4670 if (!SPEC_USIGN (TETYPE (root->left->left)))
4673 if (!IS_AST_LIT_VALUE (root->left->right) ||
4674 !IS_AST_LIT_VALUE (root->right->right))
4677 /* make sure it is the same expression */
4678 if (!isAstEqual (root->left->left,
4682 if (AST_LIT_VALUE (root->left->right) !=
4683 (getSize (TTYPE (root->left->left)) * 4))
4686 if (AST_LIT_VALUE (root->right->right) !=
4687 (getSize (TTYPE (root->left->left)) * 4))
4690 /* make sure the port supports SWAP */
4691 if (port->hasExtBitOp
4692 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4695 /* found it : create the AST */
4696 return newNode (SWAP, root->left->left, NULL);
4700 /* not found return root */
4704 /*-----------------------------------------------------------------*/
4705 /* optimizeCompare - otimizes compares for bit variables */
4706 /*-----------------------------------------------------------------*/
4708 optimizeCompare (ast * root)
4710 ast *optExpr = NULL;
4713 unsigned int litValue;
4715 /* if nothing then return nothing */
4719 /* if not a compare op then do leaves */
4720 if (!IS_COMPARE_OP (root))
4722 root->left = optimizeCompare (root->left);
4723 root->right = optimizeCompare (root->right);
4727 /* if left & right are the same then depending
4728 of the operation do */
4729 if (isAstEqual (root->left, root->right))
4731 switch (root->opval.op)
4736 optExpr = newAst_VALUE (constVal ("0"));
4741 optExpr = newAst_VALUE (constVal ("1"));
4745 return decorateType (optExpr);
4748 vleft = (root->left->type == EX_VALUE ?
4749 root->left->opval.val : NULL);
4751 vright = (root->right->type == EX_VALUE ?
4752 root->right->opval.val : NULL);
4754 /* if left is a BITVAR in BITSPACE */
4755 /* and right is a LITERAL then opt- */
4756 /* imize else do nothing */
4757 if (vleft && vright &&
4758 IS_BITVAR (vleft->etype) &&
4759 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4760 IS_LITERAL (vright->etype))
4763 /* if right side > 1 then comparison may never succeed */
4764 if ((litValue = (int) floatFromVal (vright)) > 1)
4766 werror (W_BAD_COMPARE);
4772 switch (root->opval.op)
4774 case '>': /* bit value greater than 1 cannot be */
4775 werror (W_BAD_COMPARE);
4779 case '<': /* bit value < 1 means 0 */
4781 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4784 case LE_OP: /* bit value <= 1 means no check */
4785 optExpr = newAst_VALUE (vright);
4788 case GE_OP: /* bit value >= 1 means only check for = */
4790 optExpr = newAst_VALUE (vleft);
4795 { /* literal is zero */
4796 switch (root->opval.op)
4798 case '<': /* bit value < 0 cannot be */
4799 werror (W_BAD_COMPARE);
4803 case '>': /* bit value > 0 means 1 */
4805 optExpr = newAst_VALUE (vleft);
4808 case LE_OP: /* bit value <= 0 means no check */
4809 case GE_OP: /* bit value >= 0 means no check */
4810 werror (W_BAD_COMPARE);
4814 case EQ_OP: /* bit == 0 means ! of bit */
4815 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4819 return decorateType (resolveSymbols (optExpr));
4820 } /* end-of-if of BITVAR */
4825 /*-----------------------------------------------------------------*/
4826 /* addSymToBlock : adds the symbol to the first block we find */
4827 /*-----------------------------------------------------------------*/
4829 addSymToBlock (symbol * sym, ast * tree)
4831 /* reached end of tree or a leaf */
4832 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4836 if (IS_AST_OP (tree) &&
4837 tree->opval.op == BLOCK)
4840 symbol *lsym = copySymbol (sym);
4842 lsym->next = AST_VALUES (tree, sym);
4843 AST_VALUES (tree, sym) = lsym;
4847 addSymToBlock (sym, tree->left);
4848 addSymToBlock (sym, tree->right);
4851 /*-----------------------------------------------------------------*/
4852 /* processRegParms - do processing for register parameters */
4853 /*-----------------------------------------------------------------*/
4855 processRegParms (value * args, ast * body)
4859 if (IS_REGPARM (args->etype))
4860 addSymToBlock (args->sym, body);
4865 /*-----------------------------------------------------------------*/
4866 /* resetParmKey - resets the operandkeys for the symbols */
4867 /*-----------------------------------------------------------------*/
4868 DEFSETFUNC (resetParmKey)
4879 /*-----------------------------------------------------------------*/
4880 /* createFunction - This is the key node that calls the iCode for */
4881 /* generating the code for a function. Note code */
4882 /* is generated function by function, later when */
4883 /* add inter-procedural analysis this will change */
4884 /*-----------------------------------------------------------------*/
4886 createFunction (symbol * name, ast * body)
4892 iCode *piCode = NULL;
4894 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4895 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4897 /* if check function return 0 then some problem */
4898 if (checkFunction (name, NULL) == 0)
4901 /* create a dummy block if none exists */
4903 body = newNode (BLOCK, NULL, NULL);
4907 /* check if the function name already in the symbol table */
4908 if ((csym = findSym (SymbolTab, NULL, name->name)))
4911 /* special case for compiler defined functions
4912 we need to add the name to the publics list : this
4913 actually means we are now compiling the compiler
4917 addSet (&publics, name);
4923 allocVariables (name);
4925 name->lastLine = mylineno;
4928 /* set the stack pointer */
4929 /* PENDING: check this for the mcs51 */
4930 stackPtr = -port->stack.direction * port->stack.call_overhead;
4931 if (IFFUNC_ISISR (name->type))
4932 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4933 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4934 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4936 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4938 fetype = getSpec (name->type); /* get the specifier for the function */
4939 /* if this is a reentrant function then */
4940 if (IFFUNC_ISREENT (name->type))
4943 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4945 /* do processing for parameters that are passed in registers */
4946 processRegParms (FUNC_ARGS(name->type), body);
4948 /* set the stack pointer */
4952 /* allocate & autoinit the block variables */
4953 processBlockVars (body, &stack, ALLOCATE);
4955 /* save the stack information */
4956 if (options.useXstack)
4957 name->xstack = SPEC_STAK (fetype) = stack;
4959 name->stack = SPEC_STAK (fetype) = stack;
4961 /* name needs to be mangled */
4962 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4964 body = resolveSymbols (body); /* resolve the symbols */
4965 body = decorateType (body); /* propagateType & do semantic checks */
4967 ex = newAst_VALUE (symbolVal (name)); /* create name */
4968 ex = newNode (FUNCTION, ex, body);
4969 ex->values.args = FUNC_ARGS(name->type);
4971 if (options.dump_tree) PA(ex);
4974 werror (E_FUNC_NO_CODE, name->name);
4978 /* create the node & generate intermediate code */
4980 codeOutFile = code->oFile;
4981 piCode = iCodeFromAst (ex);
4985 werror (E_FUNC_NO_CODE, name->name);
4989 eBBlockFromiCode (piCode);
4991 /* if there are any statics then do them */
4994 GcurMemmap = statsg;
4995 codeOutFile = statsg->oFile;
4996 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
5002 /* dealloc the block variables */
5003 processBlockVars (body, &stack, DEALLOCATE);
5004 outputDebugStackSymbols();
5005 /* deallocate paramaters */
5006 deallocParms (FUNC_ARGS(name->type));
5008 if (IFFUNC_ISREENT (name->type))
5011 /* we are done freeup memory & cleanup */
5013 if (port->reset_labelKey) labelKey = 1;
5015 FUNC_HASBODY(name->type) = 1;
5016 addSet (&operKeyReset, name);
5017 applyToSet (operKeyReset, resetParmKey);
5022 cleanUpLevel (LabelTab, 0);
5023 cleanUpBlock (StructTab, 1);
5024 cleanUpBlock (TypedefTab, 1);
5026 xstack->syms = NULL;
5027 istack->syms = NULL;
5032 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5033 /*-----------------------------------------------------------------*/
5034 /* ast_print : prints the ast (for debugging purposes) */
5035 /*-----------------------------------------------------------------*/
5037 void ast_print (ast * tree, FILE *outfile, int indent)
5042 /* can print only decorated trees */
5043 if (!tree->decorated) return;
5045 /* if any child is an error | this one is an error do nothing */
5046 if (tree->isError ||
5047 (tree->left && tree->left->isError) ||
5048 (tree->right && tree->right->isError)) {
5049 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5053 /* print the line */
5054 /* if not block & function */
5055 if (tree->type == EX_OP &&
5056 (tree->opval.op != FUNCTION &&
5057 tree->opval.op != BLOCK &&
5058 tree->opval.op != NULLOP)) {
5061 if (tree->opval.op == FUNCTION) {
5063 value *args=FUNC_ARGS(tree->left->opval.val->type);
5064 fprintf(outfile,"FUNCTION (%s=%p) type (",
5065 tree->left->opval.val->name, tree);
5066 printTypeChain (tree->left->opval.val->type->next,outfile);
5067 fprintf(outfile,") args (");
5070 fprintf (outfile, ", ");
5072 printTypeChain (args ? args->type : NULL, outfile);
5074 args= args ? args->next : NULL;
5076 fprintf(outfile,")\n");
5077 ast_print(tree->left,outfile,indent);
5078 ast_print(tree->right,outfile,indent);
5081 if (tree->opval.op == BLOCK) {
5082 symbol *decls = tree->values.sym;
5083 INDENT(indent,outfile);
5084 fprintf(outfile,"{\n");
5086 INDENT(indent+2,outfile);
5087 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5088 decls->name, decls);
5089 printTypeChain(decls->type,outfile);
5090 fprintf(outfile,")\n");
5092 decls = decls->next;
5094 ast_print(tree->right,outfile,indent+2);
5095 INDENT(indent,outfile);
5096 fprintf(outfile,"}\n");
5099 if (tree->opval.op == NULLOP) {
5100 ast_print(tree->left,outfile,indent);
5101 ast_print(tree->right,outfile,indent);
5104 INDENT(indent,outfile);
5106 /*------------------------------------------------------------------*/
5107 /*----------------------------*/
5108 /* leaf has been reached */
5109 /*----------------------------*/
5110 /* if this is of type value */
5111 /* just get the type */
5112 if (tree->type == EX_VALUE) {
5114 if (IS_LITERAL (tree->opval.val->etype)) {
5115 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5116 if (SPEC_USIGN (tree->opval.val->etype))
5117 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5119 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5120 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5121 floatFromVal(tree->opval.val));
5122 } else if (tree->opval.val->sym) {
5123 /* if the undefined flag is set then give error message */
5124 if (tree->opval.val->sym->undefined) {
5125 fprintf(outfile,"UNDEFINED SYMBOL ");
5127 fprintf(outfile,"SYMBOL ");
5129 fprintf(outfile,"(%s=%p)",
5130 tree->opval.val->sym->name,tree);
5133 fprintf(outfile," type (");
5134 printTypeChain(tree->ftype,outfile);
5135 fprintf(outfile,")\n");
5137 fprintf(outfile,"\n");
5142 /* if type link for the case of cast */
5143 if (tree->type == EX_LINK) {
5144 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5145 printTypeChain(tree->opval.lnk,outfile);
5146 fprintf(outfile,")\n");
5151 /* depending on type of operator do */
5153 switch (tree->opval.op) {
5154 /*------------------------------------------------------------------*/
5155 /*----------------------------*/
5157 /*----------------------------*/
5159 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5160 printTypeChain(tree->ftype,outfile);
5161 fprintf(outfile,")\n");
5162 ast_print(tree->left,outfile,indent+2);
5163 ast_print(tree->right,outfile,indent+2);
5166 /*------------------------------------------------------------------*/
5167 /*----------------------------*/
5169 /*----------------------------*/
5171 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5172 printTypeChain(tree->ftype,outfile);
5173 fprintf(outfile,")\n");
5174 ast_print(tree->left,outfile,indent+2);
5175 ast_print(tree->right,outfile,indent+2);
5178 /*------------------------------------------------------------------*/
5179 /*----------------------------*/
5180 /* struct/union pointer */
5181 /*----------------------------*/
5183 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5184 printTypeChain(tree->ftype,outfile);
5185 fprintf(outfile,")\n");
5186 ast_print(tree->left,outfile,indent+2);
5187 ast_print(tree->right,outfile,indent+2);
5190 /*------------------------------------------------------------------*/
5191 /*----------------------------*/
5192 /* ++/-- operation */
5193 /*----------------------------*/
5196 fprintf(outfile,"post-");
5198 fprintf(outfile,"pre-");
5199 fprintf(outfile,"INC_OP (%p) type (",tree);
5200 printTypeChain(tree->ftype,outfile);
5201 fprintf(outfile,")\n");
5202 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5203 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5208 fprintf(outfile,"post-");
5210 fprintf(outfile,"pre-");
5211 fprintf(outfile,"DEC_OP (%p) type (",tree);
5212 printTypeChain(tree->ftype,outfile);
5213 fprintf(outfile,")\n");
5214 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5215 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5218 /*------------------------------------------------------------------*/
5219 /*----------------------------*/
5221 /*----------------------------*/
5224 fprintf(outfile,"& (%p) type (",tree);
5225 printTypeChain(tree->ftype,outfile);
5226 fprintf(outfile,")\n");
5227 ast_print(tree->left,outfile,indent+2);
5228 ast_print(tree->right,outfile,indent+2);
5230 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5231 printTypeChain(tree->ftype,outfile);
5232 fprintf(outfile,")\n");
5233 ast_print(tree->left,outfile,indent+2);
5234 ast_print(tree->right,outfile,indent+2);
5237 /*----------------------------*/
5239 /*----------------------------*/
5241 fprintf(outfile,"OR (%p) type (",tree);
5242 printTypeChain(tree->ftype,outfile);
5243 fprintf(outfile,")\n");
5244 ast_print(tree->left,outfile,indent+2);
5245 ast_print(tree->right,outfile,indent+2);
5247 /*------------------------------------------------------------------*/
5248 /*----------------------------*/
5250 /*----------------------------*/
5252 fprintf(outfile,"XOR (%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 /*------------------------------------------------------------------*/
5260 /*----------------------------*/
5262 /*----------------------------*/
5264 fprintf(outfile,"DIV (%p) type (",tree);
5265 printTypeChain(tree->ftype,outfile);
5266 fprintf(outfile,")\n");
5267 ast_print(tree->left,outfile,indent+2);
5268 ast_print(tree->right,outfile,indent+2);
5270 /*------------------------------------------------------------------*/
5271 /*----------------------------*/
5273 /*----------------------------*/
5275 fprintf(outfile,"MOD (%p) type (",tree);
5276 printTypeChain(tree->ftype,outfile);
5277 fprintf(outfile,")\n");
5278 ast_print(tree->left,outfile,indent+2);
5279 ast_print(tree->right,outfile,indent+2);
5282 /*------------------------------------------------------------------*/
5283 /*----------------------------*/
5284 /* address dereference */
5285 /*----------------------------*/
5286 case '*': /* can be unary : if right is null then unary operation */
5288 fprintf(outfile,"DEREF (%p) type (",tree);
5289 printTypeChain(tree->ftype,outfile);
5290 fprintf(outfile,")\n");
5291 ast_print(tree->left,outfile,indent+2);
5294 /*------------------------------------------------------------------*/
5295 /*----------------------------*/
5296 /* multiplication */
5297 /*----------------------------*/
5298 fprintf(outfile,"MULT (%p) type (",tree);
5299 printTypeChain(tree->ftype,outfile);
5300 fprintf(outfile,")\n");
5301 ast_print(tree->left,outfile,indent+2);
5302 ast_print(tree->right,outfile,indent+2);
5306 /*------------------------------------------------------------------*/
5307 /*----------------------------*/
5308 /* unary '+' operator */
5309 /*----------------------------*/
5313 fprintf(outfile,"UPLUS (%p) type (",tree);
5314 printTypeChain(tree->ftype,outfile);
5315 fprintf(outfile,")\n");
5316 ast_print(tree->left,outfile,indent+2);
5318 /*------------------------------------------------------------------*/
5319 /*----------------------------*/
5321 /*----------------------------*/
5322 fprintf(outfile,"ADD (%p) type (",tree);
5323 printTypeChain(tree->ftype,outfile);
5324 fprintf(outfile,")\n");
5325 ast_print(tree->left,outfile,indent+2);
5326 ast_print(tree->right,outfile,indent+2);
5329 /*------------------------------------------------------------------*/
5330 /*----------------------------*/
5332 /*----------------------------*/
5333 case '-': /* can be unary */
5335 fprintf(outfile,"UMINUS (%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,"SUB (%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 /*----------------------------*/
5356 fprintf(outfile,"COMPL (%p) type (",tree);
5357 printTypeChain(tree->ftype,outfile);
5358 fprintf(outfile,")\n");
5359 ast_print(tree->left,outfile,indent+2);
5361 /*------------------------------------------------------------------*/
5362 /*----------------------------*/
5364 /*----------------------------*/
5366 fprintf(outfile,"NOT (%p) type (",tree);
5367 printTypeChain(tree->ftype,outfile);
5368 fprintf(outfile,")\n");
5369 ast_print(tree->left,outfile,indent+2);
5371 /*------------------------------------------------------------------*/
5372 /*----------------------------*/
5374 /*----------------------------*/
5376 fprintf(outfile,"RRC (%p) type (",tree);
5377 printTypeChain(tree->ftype,outfile);
5378 fprintf(outfile,")\n");
5379 ast_print(tree->left,outfile,indent+2);
5383 fprintf(outfile,"RLC (%p) type (",tree);
5384 printTypeChain(tree->ftype,outfile);
5385 fprintf(outfile,")\n");
5386 ast_print(tree->left,outfile,indent+2);
5389 fprintf(outfile,"SWAP (%p) type (",tree);
5390 printTypeChain(tree->ftype,outfile);
5391 fprintf(outfile,")\n");
5392 ast_print(tree->left,outfile,indent+2);
5395 fprintf(outfile,"GETHBIT (%p) type (",tree);
5396 printTypeChain(tree->ftype,outfile);
5397 fprintf(outfile,")\n");
5398 ast_print(tree->left,outfile,indent+2);
5401 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5402 printTypeChain(tree->ftype,outfile);
5403 fprintf(outfile,")\n");
5404 ast_print(tree->left,outfile,indent+2);
5405 ast_print(tree->right,outfile,indent+2);
5408 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5409 printTypeChain(tree->ftype,outfile);
5410 fprintf(outfile,")\n");
5411 ast_print(tree->left,outfile,indent+2);
5412 ast_print(tree->right,outfile,indent+2);
5414 /*------------------------------------------------------------------*/
5415 /*----------------------------*/
5417 /*----------------------------*/
5418 case CAST: /* change the type */
5419 fprintf(outfile,"CAST (%p) from type (",tree);
5420 printTypeChain(tree->right->ftype,outfile);
5421 fprintf(outfile,") to type (");
5422 printTypeChain(tree->ftype,outfile);
5423 fprintf(outfile,")\n");
5424 ast_print(tree->right,outfile,indent+2);
5428 fprintf(outfile,"ANDAND (%p) type (",tree);
5429 printTypeChain(tree->ftype,outfile);
5430 fprintf(outfile,")\n");
5431 ast_print(tree->left,outfile,indent+2);
5432 ast_print(tree->right,outfile,indent+2);
5435 fprintf(outfile,"OROR (%p) type (",tree);
5436 printTypeChain(tree->ftype,outfile);
5437 fprintf(outfile,")\n");
5438 ast_print(tree->left,outfile,indent+2);
5439 ast_print(tree->right,outfile,indent+2);
5442 /*------------------------------------------------------------------*/
5443 /*----------------------------*/
5444 /* comparison operators */
5445 /*----------------------------*/
5447 fprintf(outfile,"GT(>) (%p) type (",tree);
5448 printTypeChain(tree->ftype,outfile);
5449 fprintf(outfile,")\n");
5450 ast_print(tree->left,outfile,indent+2);
5451 ast_print(tree->right,outfile,indent+2);
5454 fprintf(outfile,"LT(<) (%p) type (",tree);
5455 printTypeChain(tree->ftype,outfile);
5456 fprintf(outfile,")\n");
5457 ast_print(tree->left,outfile,indent+2);
5458 ast_print(tree->right,outfile,indent+2);
5461 fprintf(outfile,"LE(<=) (%p) type (",tree);
5462 printTypeChain(tree->ftype,outfile);
5463 fprintf(outfile,")\n");
5464 ast_print(tree->left,outfile,indent+2);
5465 ast_print(tree->right,outfile,indent+2);
5468 fprintf(outfile,"GE(>=) (%p) type (",tree);
5469 printTypeChain(tree->ftype,outfile);
5470 fprintf(outfile,")\n");
5471 ast_print(tree->left,outfile,indent+2);
5472 ast_print(tree->right,outfile,indent+2);
5475 fprintf(outfile,"EQ(==) (%p) type (",tree);
5476 printTypeChain(tree->ftype,outfile);
5477 fprintf(outfile,")\n");
5478 ast_print(tree->left,outfile,indent+2);
5479 ast_print(tree->right,outfile,indent+2);
5482 fprintf(outfile,"NE(!=) (%p) type (",tree);
5483 printTypeChain(tree->ftype,outfile);
5484 fprintf(outfile,")\n");
5485 ast_print(tree->left,outfile,indent+2);
5486 ast_print(tree->right,outfile,indent+2);
5487 /*------------------------------------------------------------------*/
5488 /*----------------------------*/
5490 /*----------------------------*/
5491 case SIZEOF: /* evaluate wihout code generation */
5492 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5495 /*------------------------------------------------------------------*/
5496 /*----------------------------*/
5497 /* conditional operator '?' */
5498 /*----------------------------*/
5500 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5501 printTypeChain(tree->ftype,outfile);
5502 fprintf(outfile,")\n");
5503 ast_print(tree->left,outfile,indent+2);
5504 ast_print(tree->right,outfile,indent+2);
5508 fprintf(outfile,"COLON(:) (%p) type (",tree);
5509 printTypeChain(tree->ftype,outfile);
5510 fprintf(outfile,")\n");
5511 ast_print(tree->left,outfile,indent+2);
5512 ast_print(tree->right,outfile,indent+2);
5515 /*------------------------------------------------------------------*/
5516 /*----------------------------*/
5517 /* assignment operators */
5518 /*----------------------------*/
5520 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5521 printTypeChain(tree->ftype,outfile);
5522 fprintf(outfile,")\n");
5523 ast_print(tree->left,outfile,indent+2);
5524 ast_print(tree->right,outfile,indent+2);
5527 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5528 printTypeChain(tree->ftype,outfile);
5529 fprintf(outfile,")\n");
5530 ast_print(tree->left,outfile,indent+2);
5531 ast_print(tree->right,outfile,indent+2);
5534 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5535 printTypeChain(tree->ftype,outfile);
5536 fprintf(outfile,")\n");
5537 ast_print(tree->left,outfile,indent+2);
5538 ast_print(tree->right,outfile,indent+2);
5541 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5542 printTypeChain(tree->ftype,outfile);
5543 fprintf(outfile,")\n");
5544 ast_print(tree->left,outfile,indent+2);
5545 ast_print(tree->right,outfile,indent+2);
5548 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5549 printTypeChain(tree->ftype,outfile);
5550 fprintf(outfile,")\n");
5551 ast_print(tree->left,outfile,indent+2);
5552 ast_print(tree->right,outfile,indent+2);
5555 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5556 printTypeChain(tree->ftype,outfile);
5557 fprintf(outfile,")\n");
5558 ast_print(tree->left,outfile,indent+2);
5559 ast_print(tree->right,outfile,indent+2);
5562 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5563 printTypeChain(tree->ftype,outfile);
5564 fprintf(outfile,")\n");
5565 ast_print(tree->left,outfile,indent+2);
5566 ast_print(tree->right,outfile,indent+2);
5568 /*------------------------------------------------------------------*/
5569 /*----------------------------*/
5571 /*----------------------------*/
5573 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5574 printTypeChain(tree->ftype,outfile);
5575 fprintf(outfile,")\n");
5576 ast_print(tree->left,outfile,indent+2);
5577 ast_print(tree->right,outfile,indent+2);
5579 /*------------------------------------------------------------------*/
5580 /*----------------------------*/
5582 /*----------------------------*/
5584 fprintf(outfile,"ADDASS(+=) (%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 /*----------------------------*/
5592 /* straight assignemnt */
5593 /*----------------------------*/
5595 fprintf(outfile,"ASSIGN(=) (%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 /*----------------------------*/
5603 /* comma operator */
5604 /*----------------------------*/
5606 fprintf(outfile,"COMMA(,) (%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 /*----------------------------*/
5615 /*----------------------------*/
5618 fprintf(outfile,"CALL (%p) type (",tree);
5619 printTypeChain(tree->ftype,outfile);
5620 fprintf(outfile,")\n");
5621 ast_print(tree->left,outfile,indent+2);
5622 ast_print(tree->right,outfile,indent+2);
5625 fprintf(outfile,"PARMS\n");
5626 ast_print(tree->left,outfile,indent+2);
5627 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5628 ast_print(tree->right,outfile,indent+2);
5631 /*------------------------------------------------------------------*/
5632 /*----------------------------*/
5633 /* return statement */
5634 /*----------------------------*/
5636 fprintf(outfile,"RETURN (%p) type (",tree);
5638 printTypeChain(tree->right->ftype,outfile);
5640 fprintf(outfile,")\n");
5641 ast_print(tree->right,outfile,indent+2);
5643 /*------------------------------------------------------------------*/
5644 /*----------------------------*/
5645 /* label statement */
5646 /*----------------------------*/
5648 fprintf(outfile,"LABEL (%p)\n",tree);
5649 ast_print(tree->left,outfile,indent+2);
5650 ast_print(tree->right,outfile,indent);
5652 /*------------------------------------------------------------------*/
5653 /*----------------------------*/
5654 /* switch statement */
5655 /*----------------------------*/
5659 fprintf(outfile,"SWITCH (%p) ",tree);
5660 ast_print(tree->left,outfile,0);
5661 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5662 INDENT(indent+2,outfile);
5663 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5664 (int) floatFromVal(val),
5665 tree->values.switchVals.swNum,
5666 (int) floatFromVal(val));
5668 ast_print(tree->right,outfile,indent);
5671 /*------------------------------------------------------------------*/
5672 /*----------------------------*/
5674 /*----------------------------*/
5676 fprintf(outfile,"IF (%p) \n",tree);
5677 ast_print(tree->left,outfile,indent+2);
5678 if (tree->trueLabel) {
5679 INDENT(indent+2,outfile);
5680 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5682 if (tree->falseLabel) {
5683 INDENT(indent+2,outfile);
5684 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5686 ast_print(tree->right,outfile,indent+2);
5688 /*----------------------------*/
5689 /* goto Statement */
5690 /*----------------------------*/
5692 fprintf(outfile,"GOTO (%p) \n",tree);
5693 ast_print(tree->left,outfile,indent+2);
5694 fprintf(outfile,"\n");
5696 /*------------------------------------------------------------------*/
5697 /*----------------------------*/
5699 /*----------------------------*/
5701 fprintf(outfile,"FOR (%p) \n",tree);
5702 if (AST_FOR( tree, initExpr)) {
5703 INDENT(indent+2,outfile);
5704 fprintf(outfile,"INIT EXPR ");
5705 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5707 if (AST_FOR( tree, condExpr)) {
5708 INDENT(indent+2,outfile);
5709 fprintf(outfile,"COND EXPR ");
5710 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5712 if (AST_FOR( tree, loopExpr)) {
5713 INDENT(indent+2,outfile);
5714 fprintf(outfile,"LOOP EXPR ");
5715 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5717 fprintf(outfile,"FOR LOOP BODY \n");
5718 ast_print(tree->left,outfile,indent+2);
5721 fprintf(outfile,"CRITICAL (%p) \n",tree);
5722 ast_print(tree->left,outfile,indent+2);
5730 ast_print(t,stdout,0);
5735 /*-----------------------------------------------------------------*/
5736 /* astErrors : returns non-zero if errors present in tree */
5737 /*-----------------------------------------------------------------*/
5738 int astErrors(ast *t)
5747 if (t->type == EX_VALUE
5748 && t->opval.val->sym
5749 && t->opval.val->sym->undefined)
5752 errors += astErrors(t->left);
5753 errors += astErrors(t->right);