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