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 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *);
59 ast *backPatchLabels (ast *, symbol *, symbol *);
62 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
67 printTypeChain (tree->ftype, stdout);
72 /*-----------------------------------------------------------------*/
73 /* newAst - creates a fresh node for an expression tree */
74 /*-----------------------------------------------------------------*/
76 newAst_ (unsigned type)
79 static int oldLineno = 0;
81 ex = Safe_alloc ( sizeof (ast));
84 ex->lineno = (noLineno ? oldLineno : mylineno);
85 ex->filename = currFname;
86 ex->level = NestLevel;
87 ex->block = currBlockno;
88 ex->initMode = inInitMode;
89 ex->seqPoint = seqPointNo;
94 newAst_VALUE (value * val)
96 ast *ex = newAst_ (EX_VALUE);
102 newAst_OP (unsigned op)
104 ast *ex = newAst_ (EX_OP);
110 newAst_LINK (sym_link * val)
112 ast *ex = newAst_ (EX_LINK);
117 /*-----------------------------------------------------------------*/
118 /* newNode - creates a new node */
119 /*-----------------------------------------------------------------*/
121 newNode (long op, ast * left, ast * right)
132 /*-----------------------------------------------------------------*/
133 /* newIfxNode - creates a new Ifx Node */
134 /*-----------------------------------------------------------------*/
136 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
140 /* if this is a literal then we already know the result */
141 if (condAst->etype && IS_LITERAL (condAst->etype))
143 /* then depending on the expression value */
144 if (floatFromVal (condAst->opval.val))
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (trueLabel)),
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (falseLabel)),
155 ifxNode = newNode (IFX, condAst, NULL);
156 ifxNode->trueLabel = trueLabel;
157 ifxNode->falseLabel = falseLabel;
163 /*-----------------------------------------------------------------*/
164 /* copyAstValues - copies value portion of ast if needed */
165 /*-----------------------------------------------------------------*/
167 copyAstValues (ast * dest, ast * src)
169 switch (src->opval.op)
172 dest->values.sym = copySymbolChain (src->values.sym);
176 dest->values.switchVals.swVals =
177 copyValue (src->values.switchVals.swVals);
178 dest->values.switchVals.swDefault =
179 src->values.switchVals.swDefault;
180 dest->values.switchVals.swNum =
181 src->values.switchVals.swNum;
185 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
189 dest->values.constlist = copyLiteralList(src->values.constlist);
193 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
194 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
195 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
196 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
197 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
198 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
199 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
204 /*-----------------------------------------------------------------*/
205 /* copyAst - makes a copy of a given astession */
206 /*-----------------------------------------------------------------*/
215 dest = Safe_alloc ( sizeof (ast));
217 dest->type = src->type;
218 dest->lineno = src->lineno;
219 dest->level = src->level;
220 dest->funcName = src->funcName;
221 dest->reversed = src->reversed;
224 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
226 /* if this is a leaf */
228 if (src->type == EX_VALUE)
230 dest->opval.val = copyValue (src->opval.val);
235 if (src->type == EX_LINK)
237 dest->opval.lnk = copyLinkChain (src->opval.lnk);
241 dest->opval.op = src->opval.op;
243 /* if this is a node that has special values */
244 copyAstValues (dest, src);
246 dest->trueLabel = copySymbol (src->trueLabel);
247 dest->falseLabel = copySymbol (src->falseLabel);
248 dest->left = copyAst (src->left);
249 dest->right = copyAst (src->right);
255 /*-----------------------------------------------------------------*/
256 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
257 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
258 /*-----------------------------------------------------------------*/
259 ast *removeIncDecOps (ast * tree) {
261 // traverse the tree and remove inc/dec ops
266 if (tree->type == EX_OP &&
267 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
274 tree->left=removeIncDecOps(tree->left);
275 tree->right=removeIncDecOps(tree->right);
280 /*-----------------------------------------------------------------*/
281 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
282 /* "*++s += 3" -> "*++s = *++s + 3" */
283 /*-----------------------------------------------------------------*/
284 ast *removePreIncDecOps (ast * tree) {
286 // traverse the tree and remove pre-inc/dec ops
291 if (tree->type == EX_OP &&
292 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
297 tree->left=removePreIncDecOps(tree->left);
298 tree->right=removePreIncDecOps(tree->right);
303 /*-----------------------------------------------------------------*/
304 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
305 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
306 /*-----------------------------------------------------------------*/
307 ast *removePostIncDecOps (ast * tree) {
309 // traverse the tree and remove pre-inc/dec ops
314 if (tree->type == EX_OP &&
315 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
320 tree->left=removePostIncDecOps(tree->left);
321 tree->right=removePostIncDecOps(tree->right);
326 /*-----------------------------------------------------------------*/
327 /* hasSEFcalls - returns TRUE if tree has a function call */
328 /*-----------------------------------------------------------------*/
330 hasSEFcalls (ast * tree)
335 if (tree->type == EX_OP &&
336 (tree->opval.op == CALL ||
337 tree->opval.op == PCALL ||
338 tree->opval.op == '=' ||
339 tree->opval.op == INC_OP ||
340 tree->opval.op == DEC_OP))
343 return (hasSEFcalls (tree->left) |
344 hasSEFcalls (tree->right));
347 /*-----------------------------------------------------------------*/
348 /* isAstEqual - compares two asts & returns 1 if they are equal */
349 /*-----------------------------------------------------------------*/
351 isAstEqual (ast * t1, ast * t2)
360 if (t1->type != t2->type)
366 if (t1->opval.op != t2->opval.op)
368 return (isAstEqual (t1->left, t2->left) &&
369 isAstEqual (t1->right, t2->right));
373 if (t1->opval.val->sym)
375 if (!t2->opval.val->sym)
378 return isSymbolEqual (t1->opval.val->sym,
383 if (t2->opval.val->sym)
386 return (floatFromVal (t1->opval.val) ==
387 floatFromVal (t2->opval.val));
391 /* only compare these two types */
399 /*-----------------------------------------------------------------*/
400 /* resolveSymbols - resolve symbols from the symbol table */
401 /*-----------------------------------------------------------------*/
403 resolveSymbols (ast * tree)
405 /* walk the entire tree and check for values */
406 /* with symbols if we find one then replace */
407 /* symbol with that from the symbol table */
414 /* if not block & function */
415 if (tree->type == EX_OP &&
416 (tree->opval.op != FUNCTION &&
417 tree->opval.op != BLOCK &&
418 tree->opval.op != NULLOP))
420 filename = tree->filename;
421 lineno = tree->lineno;
425 /* make sure we resolve the true & false labels for ifx */
426 if (tree->type == EX_OP && tree->opval.op == IFX)
432 if ((csym = findSym (LabelTab, tree->trueLabel,
433 tree->trueLabel->name)))
434 tree->trueLabel = csym;
436 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
437 tree->trueLabel->name);
440 if (tree->falseLabel)
442 if ((csym = findSym (LabelTab,
444 tree->falseLabel->name)))
445 tree->falseLabel = csym;
447 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
448 tree->falseLabel->name);
453 /* if this is a label resolve it from the labelTab */
454 if (IS_AST_VALUE (tree) &&
455 tree->opval.val->sym &&
456 tree->opval.val->sym->islbl)
459 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
460 tree->opval.val->sym->name);
463 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
464 tree->opval.val->sym->name);
466 tree->opval.val->sym = csym;
468 goto resolveChildren;
471 /* do only for leafs */
472 if (IS_AST_VALUE (tree) &&
473 tree->opval.val->sym &&
474 !tree->opval.val->sym->implicit)
477 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
479 /* if found in the symbol table & they r not the same */
480 if (csym && tree->opval.val->sym != csym)
482 tree->opval.val->sym = csym;
483 tree->opval.val->type = csym->type;
484 tree->opval.val->etype = csym->etype;
487 /* if not found in the symbol table */
488 /* mark it as undefined assume it is */
489 /* an integer in data space */
490 if (!csym && !tree->opval.val->sym->implicit)
493 /* if this is a function name then */
494 /* mark it as returning an int */
497 tree->opval.val->sym->type = newLink (DECLARATOR);
498 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
499 tree->opval.val->sym->type->next =
500 tree->opval.val->sym->etype = newIntLink ();
501 tree->opval.val->etype = tree->opval.val->etype;
502 tree->opval.val->type = tree->opval.val->sym->type;
503 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
504 tree->opval.val->sym->name);
505 //tree->opval.val->sym->undefined = 1;
506 allocVariables (tree->opval.val->sym);
510 tree->opval.val->sym->undefined = 1;
511 tree->opval.val->type =
512 tree->opval.val->etype = newIntLink ();
513 tree->opval.val->sym->type =
514 tree->opval.val->sym->etype = newIntLink ();
520 resolveSymbols (tree->left);
521 resolveSymbols (tree->right);
526 /*-----------------------------------------------------------------*/
527 /* setAstLineno - walks a ast tree & sets the line number */
528 /*-----------------------------------------------------------------*/
529 int setAstLineno (ast * tree, int lineno)
534 tree->lineno = lineno;
535 setAstLineno (tree->left, lineno);
536 setAstLineno (tree->right, lineno);
540 /*-----------------------------------------------------------------*/
541 /* funcOfType :- function of type with name */
542 /*-----------------------------------------------------------------*/
544 funcOfType (char *name, sym_link * type, sym_link * argType,
548 /* create the symbol */
549 sym = newSymbol (name, 0);
551 /* setup return value */
552 sym->type = newLink (DECLARATOR);
553 DCL_TYPE (sym->type) = FUNCTION;
554 sym->type->next = copyLinkChain (type);
555 sym->etype = getSpec (sym->type);
556 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
558 /* if arguments required */
562 args = FUNC_ARGS(sym->type) = newValue ();
566 args->type = copyLinkChain (argType);
567 args->etype = getSpec (args->type);
568 SPEC_EXTR(args->etype)=1;
571 args = args->next = newValue ();
578 allocVariables (sym);
583 /*-----------------------------------------------------------------*/
584 /* funcOfTypeVarg :- function of type with name and argtype */
585 /*-----------------------------------------------------------------*/
587 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
592 /* create the symbol */
593 sym = newSymbol (name, 0);
595 /* setup return value */
596 sym->type = newLink (DECLARATOR);
597 DCL_TYPE (sym->type) = FUNCTION;
598 sym->type->next = typeFromStr(rtype);
599 sym->etype = getSpec (sym->type);
601 /* if arguments required */
604 args = FUNC_ARGS(sym->type) = newValue ();
606 for ( i = 0 ; i < nArgs ; i++ ) {
607 args->type = typeFromStr(atypes[i]);
608 args->etype = getSpec (args->type);
609 SPEC_EXTR(args->etype)=1;
610 if ((i + 1) == nArgs) break;
611 args = args->next = newValue ();
618 allocVariables (sym);
623 /*-----------------------------------------------------------------*/
624 /* reverseParms - will reverse a parameter tree */
625 /*-----------------------------------------------------------------*/
627 reverseParms (ast * ptree)
633 /* top down if we find a nonParm tree then quit */
634 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
636 /* The various functions expect the parameter tree to be right heavy. */
637 /* Rotate the tree to be left heavy so that after reversal it is */
638 /* right heavy again. */
639 while ((ttree = ptree->right) && ttree->type == EX_OP &&
640 ttree->opval.op == PARAM)
642 ptree->right = ttree->right;
643 ttree->right = ttree->left;
644 ttree->left = ptree->left;
650 ptree->left = ptree->right;
651 ptree->right = ttree;
653 reverseParms (ptree->left);
654 reverseParms (ptree->right);
660 /*-----------------------------------------------------------------*/
661 /* processParms - makes sure the parameters are okay and do some */
662 /* processing with them */
663 /*-----------------------------------------------------------------*/
665 processParms (ast *func,
668 int *parmNumber, /* unused, although updated */
671 RESULT_TYPE resultType;
674 /* if none of them exist */
675 if (!defParm && !*actParm)
680 if (getenv("DEBUG_SANITY"))
682 fprintf (stderr, "processParms: %s ", defParm->name);
684 /* make sure the type is complete and sane */
685 checkTypeSanity(defParm->etype, defParm->name);
688 if (IS_CODEPTR (func->ftype))
689 functype = func->ftype->next;
691 functype = func->ftype;
693 /* if the function is being called via a pointer & */
694 /* it has not been defined a reentrant then we cannot */
695 /* have parameters */
696 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
698 werror (W_NONRENT_ARGS);
703 /* if defined parameters ended but actual parameters */
704 /* exist and this is not defined as a variable arg */
705 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
707 werror (E_TOO_MANY_PARMS);
711 /* if defined parameters present but no actual parameters */
712 if (defParm && !*actParm)
714 werror (E_TOO_FEW_PARMS);
718 /* if this is a PARAM node then match left & right */
719 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
721 (*actParm)->decorated = 1;
722 return (processParms (func, defParm,
723 &(*actParm)->left, parmNumber, FALSE) ||
724 processParms (func, defParm ? defParm->next : NULL,
725 &(*actParm)->right, parmNumber, rightmost));
727 else if (defParm) /* not vararg */
729 /* If we have found a value node by following only right-hand links,
730 * then we know that there are no more values after us.
732 * Therefore, if there are more defined parameters, the caller didn't
735 if (rightmost && defParm->next)
737 werror (E_TOO_FEW_PARMS);
742 /* decorate parameter */
743 resultType = defParm ? getResultTypeFromType (defParm->etype) :
745 *actParm = decorateType (*actParm, resultType);
747 if (IS_VOID((*actParm)->ftype))
749 werror (E_VOID_VALUE_USED);
753 /* If this is a varargs function... */
754 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
759 if (IS_CAST_OP (*actParm)
760 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
762 /* Parameter was explicitly typecast; don't touch it. */
766 ftype = (*actParm)->ftype;
768 /* If it's a char, upcast to int. */
769 if (IS_INTEGRAL (ftype)
770 && (getSize (ftype) < (unsigned) INTSIZE))
772 newType = newAst_LINK(INTTYPE);
775 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
777 newType = newAst_LINK (copyLinkChain(ftype));
778 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
781 if (IS_AGGREGATE (ftype))
783 newType = newAst_LINK (copyLinkChain (ftype));
784 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
789 /* cast required; change this op to a cast. */
790 (*actParm)->decorated = 0;
791 *actParm = newNode (CAST, newType, *actParm);
792 (*actParm)->lineno = (*actParm)->right->lineno;
794 decorateType (*actParm, RESULT_TYPE_NONE);
799 /* if defined parameters ended but actual has not & */
801 if (!defParm && *actParm &&
802 (options.stackAuto || IFFUNC_ISREENT (functype)))
805 resolveSymbols (*actParm);
807 /* the parameter type must be at least castable */
808 if (compareType (defParm->type, (*actParm)->ftype) == 0)
810 werror (E_INCOMPAT_TYPES);
811 printFromToType ((*actParm)->ftype, defParm->type);
815 /* if the parameter is castable then add the cast */
816 if (compareType (defParm->type, (*actParm)->ftype) < 0)
820 resultType = getResultTypeFromType (defParm->etype);
821 pTree = resolveSymbols (copyAst (*actParm));
823 /* now change the current one to a cast */
824 (*actParm)->type = EX_OP;
825 (*actParm)->opval.op = CAST;
826 (*actParm)->left = newAst_LINK (defParm->type);
827 (*actParm)->right = pTree;
828 (*actParm)->decorated = 0; /* force typechecking */
829 decorateType (*actParm, resultType);
832 /* make a copy and change the regparm type to the defined parm */
833 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
834 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
835 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
840 /*-----------------------------------------------------------------*/
841 /* createIvalType - generates ival for basic types */
842 /*-----------------------------------------------------------------*/
844 createIvalType (ast * sym, sym_link * type, initList * ilist)
848 /* if initList is deep */
849 if (ilist->type == INIT_DEEP)
850 ilist = ilist->init.deep;
852 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
853 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
856 /*-----------------------------------------------------------------*/
857 /* createIvalStruct - generates initial value for structures */
858 /*-----------------------------------------------------------------*/
860 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
867 sflds = SPEC_STRUCT (type)->fields;
868 if (ilist->type != INIT_DEEP)
870 werror (E_INIT_STRUCT, "");
874 iloop = ilist->init.deep;
876 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
878 /* if we have come to end */
882 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
883 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
884 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE);
888 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
889 W_EXCESS_INITIALIZERS, "struct",
890 sym->opval.val->sym->name);
897 /*-----------------------------------------------------------------*/
898 /* createIvalArray - generates code for array initialization */
899 /*-----------------------------------------------------------------*/
901 createIvalArray (ast * sym, sym_link * type, initList * ilist)
905 int lcnt = 0, size = 0;
906 literalList *literalL;
908 /* take care of the special case */
909 /* array of characters can be init */
911 if (IS_CHAR (type->next))
912 if ((rast = createIvalCharPtr (sym,
914 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
916 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
918 /* not the special case */
919 if (ilist->type != INIT_DEEP)
921 werror (E_INIT_STRUCT, "");
925 iloop = ilist->init.deep;
926 lcnt = DCL_ELEM (type);
928 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
932 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
934 rast = newNode(ARRAYINIT, aSym, NULL);
935 rast->values.constlist = literalL;
937 // Make sure size is set to length of initializer list.
944 if (lcnt && size > lcnt)
946 // Array size was specified, and we have more initializers than needed.
947 char *name=sym->opval.val->sym->name;
948 int lineno=sym->opval.val->sym->lineDef;
949 char *filename=sym->opval.val->sym->fileDef;
951 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
960 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
961 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
962 rast = createIval (aSym, type->next, iloop, rast);
963 iloop = (iloop ? iloop->next : NULL);
969 /* no of elements given and we */
970 /* have generated for all of them */
973 // is this a better way? at least it won't crash
974 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
975 int lineno = iloop->lineno;
976 char *filename = iloop->filename;
977 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
984 /* if we have not been given a size */
985 if (!DCL_ELEM (type))
987 /* but this still updates the typedef instead of the instance ! see bug 770487 */
988 DCL_ELEM (type) = size;
991 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
995 /*-----------------------------------------------------------------*/
996 /* createIvalCharPtr - generates initial values for char pointers */
997 /*-----------------------------------------------------------------*/
999 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
1003 /* if this is a pointer & right is a literal array then */
1004 /* just assignment will do */
1005 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1006 SPEC_SCLS (iexpr->etype) == S_CODE)
1007 && IS_ARRAY (iexpr->ftype)))
1008 return newNode ('=', sym, iexpr);
1010 /* left side is an array so we have to assign each */
1012 if ((IS_LITERAL (iexpr->etype) ||
1013 SPEC_SCLS (iexpr->etype) == S_CODE)
1014 && IS_ARRAY (iexpr->ftype))
1016 /* for each character generate an assignment */
1017 /* to the array element */
1018 char *s = SPEC_CVAL (iexpr->etype).v_char;
1020 int size = getSize (iexpr->ftype);
1021 int symsize = getSize (type);
1025 if (size>(symsize+1))
1026 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1027 "string", sym->opval.val->sym->name);
1031 for (i=0;i<size;i++)
1033 rast = newNode (NULLOP,
1037 newAst_VALUE (valueFromLit ((float) i))),
1038 newAst_VALUE (valueFromLit (*s))));
1042 // now WE don't need iexpr's symbol anymore
1043 freeStringSymbol(AST_SYMBOL(iexpr));
1045 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1051 /*-----------------------------------------------------------------*/
1052 /* createIvalPtr - generates initial value for pointers */
1053 /*-----------------------------------------------------------------*/
1055 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1061 if (ilist->type == INIT_DEEP)
1062 ilist = ilist->init.deep;
1064 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1066 /* if character pointer */
1067 if (IS_CHAR (type->next))
1068 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1071 return newNode ('=', sym, iexpr);
1074 /*-----------------------------------------------------------------*/
1075 /* createIval - generates code for initial value */
1076 /*-----------------------------------------------------------------*/
1078 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1085 /* if structure then */
1086 if (IS_STRUCT (type))
1087 rast = createIvalStruct (sym, type, ilist);
1089 /* if this is a pointer */
1091 rast = createIvalPtr (sym, type, ilist);
1093 /* if this is an array */
1094 if (IS_ARRAY (type))
1095 rast = createIvalArray (sym, type, ilist);
1097 /* if type is SPECIFIER */
1099 rast = createIvalType (sym, type, ilist);
1102 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1104 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1107 /*-----------------------------------------------------------------*/
1108 /* initAggregates - initialises aggregate variables with initv */
1109 /*-----------------------------------------------------------------*/
1110 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1111 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1114 /*-----------------------------------------------------------------*/
1115 /* gatherAutoInit - creates assignment expressions for initial */
1117 /*-----------------------------------------------------------------*/
1119 gatherAutoInit (symbol * autoChain)
1126 for (sym = autoChain; sym; sym = sym->next)
1129 /* resolve the symbols in the ival */
1131 resolveIvalSym (sym->ival, sym->type);
1134 /* if we are PIC16 port,
1135 * and this is a static,
1136 * and have initial value,
1137 * and not S_CODE, don't emit in gs segment,
1138 * but allow glue.c:pic16emitRegularMap to put symbol
1139 * in idata section */
1140 if(TARGET_IS_PIC16 &&
1141 IS_STATIC (sym->etype) && sym->ival
1142 && SPEC_SCLS(sym->etype) != S_CODE) {
1143 SPEC_SCLS (sym->etype) = S_DATA;
1148 /* if this is a static variable & has an */
1149 /* initial value the code needs to be lifted */
1150 /* here to the main portion since they can be */
1151 /* initialised only once at the start */
1152 if (IS_STATIC (sym->etype) && sym->ival &&
1153 SPEC_SCLS (sym->etype) != S_CODE)
1157 /* insert the symbol into the symbol table */
1158 /* with level = 0 & name = rname */
1159 newSym = copySymbol (sym);
1160 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1162 /* now lift the code to main */
1163 if (IS_AGGREGATE (sym->type)) {
1164 work = initAggregates (sym, sym->ival, NULL);
1166 if (getNelements(sym->type, sym->ival)>1) {
1167 werrorfl (sym->fileDef, sym->lineDef,
1168 W_EXCESS_INITIALIZERS, "scalar",
1171 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1172 list2expr (sym->ival));
1175 setAstLineno (work, sym->lineDef);
1179 staticAutos = newNode (NULLOP, staticAutos, work);
1186 /* if there is an initial value */
1187 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1189 initList *ilist=sym->ival;
1191 while (ilist->type == INIT_DEEP) {
1192 ilist = ilist->init.deep;
1195 /* update lineno for error msg */
1196 lineno=sym->lineDef;
1197 setAstLineno (ilist->init.node, lineno);
1199 if (IS_AGGREGATE (sym->type)) {
1200 work = initAggregates (sym, sym->ival, NULL);
1202 if (getNelements(sym->type, sym->ival)>1) {
1203 werrorfl (sym->fileDef, sym->lineDef,
1204 W_EXCESS_INITIALIZERS, "scalar",
1207 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1208 list2expr (sym->ival));
1212 setAstLineno (work, sym->lineDef);
1216 init = newNode (NULLOP, init, work);
1225 /*-----------------------------------------------------------------*/
1226 /* freeStringSymbol - delete a literal string if no more usage */
1227 /*-----------------------------------------------------------------*/
1228 void freeStringSymbol(symbol *sym) {
1229 /* make sure this is a literal string */
1230 assert (sym->isstrlit);
1231 if (--sym->isstrlit == 0) { // lower the usage count
1232 memmap *segment=SPEC_OCLS(sym->etype);
1234 deleteSetItem(&segment->syms, sym);
1239 /*-----------------------------------------------------------------*/
1240 /* stringToSymbol - creates a symbol from a literal string */
1241 /*-----------------------------------------------------------------*/
1243 stringToSymbol (value * val)
1245 char name[SDCC_NAME_MAX + 1];
1246 static int charLbl = 0;
1251 // have we heard this before?
1252 for (sp=statsg->syms; sp; sp=sp->next) {
1254 size = getSize (sym->type);
1255 if (sym->isstrlit && size == getSize (val->type) &&
1256 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1257 // yes, this is old news. Don't publish it again.
1258 sym->isstrlit++; // but raise the usage count
1259 return symbolVal(sym);
1263 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1264 sym = newSymbol (name, 0); /* make it @ level 0 */
1265 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1267 /* copy the type from the value passed */
1268 sym->type = copyLinkChain (val->type);
1269 sym->etype = getSpec (sym->type);
1270 /* change to storage class & output class */
1271 SPEC_SCLS (sym->etype) = S_CODE;
1272 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1273 SPEC_STAT (sym->etype) = 1;
1274 /* make the level & block = 0 */
1275 sym->block = sym->level = 0;
1277 /* create an ival */
1278 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1283 allocVariables (sym);
1286 return symbolVal (sym);
1290 /*-----------------------------------------------------------------*/
1291 /* processBlockVars - will go thru the ast looking for block if */
1292 /* a block is found then will allocate the syms */
1293 /* will also gather the auto inits present */
1294 /*-----------------------------------------------------------------*/
1296 processBlockVars (ast * tree, int *stack, int action)
1301 /* if this is a block */
1302 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1306 if (action == ALLOCATE)
1308 *stack += allocVariables (tree->values.sym);
1309 autoInit = gatherAutoInit (tree->values.sym);
1311 /* if there are auto inits then do them */
1313 tree->left = newNode (NULLOP, autoInit, tree->left);
1315 else /* action is deallocate */
1316 deallocLocal (tree->values.sym);
1319 processBlockVars (tree->left, stack, action);
1320 processBlockVars (tree->right, stack, action);
1325 /*-------------------------------------------------------------*/
1326 /* constExprTree - returns TRUE if this tree is a constant */
1328 /*-------------------------------------------------------------*/
1329 bool constExprTree (ast *cexpr) {
1335 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1337 switch (cexpr->type)
1340 if (IS_AST_LIT_VALUE(cexpr)) {
1341 // this is a literal
1344 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1345 // a function's address will never change
1348 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1349 // an array's address will never change
1352 if (IS_AST_SYM_VALUE(cexpr) &&
1353 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1354 // a symbol in code space will never change
1355 // This is only for the 'char *s="hallo"' case and will have to leave
1356 //printf(" code space symbol");
1361 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1362 "unexpected link in expression tree\n");
1365 if (cexpr->opval.op==ARRAYINIT) {
1366 // this is a list of literals
1369 if (cexpr->opval.op=='=') {
1370 return constExprTree(cexpr->right);
1372 if (cexpr->opval.op==CAST) {
1373 // cast ignored, maybe we should throw a warning here?
1374 return constExprTree(cexpr->right);
1376 if (cexpr->opval.op=='&') {
1379 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1382 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1387 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1392 /*-----------------------------------------------------------------*/
1393 /* constExprValue - returns the value of a constant expression */
1394 /* or NULL if it is not a constant expression */
1395 /*-----------------------------------------------------------------*/
1397 constExprValue (ast * cexpr, int check)
1399 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1401 /* if this is not a constant then */
1402 if (!IS_LITERAL (cexpr->ftype))
1404 /* then check if this is a literal array
1406 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1407 SPEC_CVAL (cexpr->etype).v_char &&
1408 IS_ARRAY (cexpr->ftype))
1410 value *val = valFromType (cexpr->ftype);
1411 SPEC_SCLS (val->etype) = S_LITERAL;
1412 val->sym = cexpr->opval.val->sym;
1413 val->sym->type = copyLinkChain (cexpr->ftype);
1414 val->sym->etype = getSpec (val->sym->type);
1415 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1419 /* if we are casting a literal value then */
1420 if (IS_AST_OP (cexpr) &&
1421 cexpr->opval.op == CAST &&
1422 IS_LITERAL (cexpr->right->ftype))
1424 return valCastLiteral (cexpr->ftype,
1425 floatFromVal (cexpr->right->opval.val));
1428 if (IS_AST_VALUE (cexpr))
1430 return cexpr->opval.val;
1434 werror (E_CONST_EXPECTED, "found expression");
1439 /* return the value */
1440 return cexpr->opval.val;
1444 /*-----------------------------------------------------------------*/
1445 /* isLabelInAst - will return true if a given label is found */
1446 /*-----------------------------------------------------------------*/
1448 isLabelInAst (symbol * label, ast * tree)
1450 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1453 if (IS_AST_OP (tree) &&
1454 tree->opval.op == LABEL &&
1455 isSymbolEqual (AST_SYMBOL (tree->left), label))
1458 return isLabelInAst (label, tree->right) &&
1459 isLabelInAst (label, tree->left);
1463 /*-----------------------------------------------------------------*/
1464 /* isLoopCountable - return true if the loop count can be determi- */
1465 /* -ned at compile time . */
1466 /*-----------------------------------------------------------------*/
1468 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1469 symbol ** sym, ast ** init, ast ** end)
1472 /* the loop is considered countable if the following
1473 conditions are true :-
1475 a) initExpr :- <sym> = <const>
1476 b) condExpr :- <sym> < <const1>
1477 c) loopExpr :- <sym> ++
1480 /* first check the initExpr */
1481 if (IS_AST_OP (initExpr) &&
1482 initExpr->opval.op == '=' && /* is assignment */
1483 IS_AST_SYM_VALUE (initExpr->left))
1484 { /* left is a symbol */
1486 *sym = AST_SYMBOL (initExpr->left);
1487 *init = initExpr->right;
1492 /* for now the symbol has to be of
1494 if (!IS_INTEGRAL ((*sym)->type))
1497 /* now check condExpr */
1498 if (IS_AST_OP (condExpr))
1501 switch (condExpr->opval.op)
1504 if (IS_AST_SYM_VALUE (condExpr->left) &&
1505 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1506 IS_AST_LIT_VALUE (condExpr->right))
1508 *end = condExpr->right;
1514 if (IS_AST_OP (condExpr->left) &&
1515 condExpr->left->opval.op == '>' &&
1516 IS_AST_LIT_VALUE (condExpr->left->right) &&
1517 IS_AST_SYM_VALUE (condExpr->left->left) &&
1518 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1521 *end = newNode ('+', condExpr->left->right,
1522 newAst_VALUE (constVal ("1")));
1533 /* check loop expression is of the form <sym>++ */
1534 if (!IS_AST_OP (loopExpr))
1537 /* check if <sym> ++ */
1538 if (loopExpr->opval.op == INC_OP)
1544 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1545 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1552 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1553 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1561 if (loopExpr->opval.op == ADD_ASSIGN)
1564 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1565 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1566 IS_AST_LIT_VALUE (loopExpr->right) &&
1567 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1575 /*-----------------------------------------------------------------*/
1576 /* astHasVolatile - returns true if ast contains any volatile */
1577 /*-----------------------------------------------------------------*/
1579 astHasVolatile (ast * tree)
1584 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1587 if (IS_AST_OP (tree))
1588 return astHasVolatile (tree->left) ||
1589 astHasVolatile (tree->right);
1594 /*-----------------------------------------------------------------*/
1595 /* astHasPointer - return true if the ast contains any ptr variable */
1596 /*-----------------------------------------------------------------*/
1598 astHasPointer (ast * tree)
1603 if (IS_AST_LINK (tree))
1606 /* if we hit an array expression then check
1607 only the left side */
1608 if (IS_AST_OP (tree) && tree->opval.op == '[')
1609 return astHasPointer (tree->left);
1611 if (IS_AST_VALUE (tree))
1612 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1614 return astHasPointer (tree->left) ||
1615 astHasPointer (tree->right);
1619 /*-----------------------------------------------------------------*/
1620 /* astHasSymbol - return true if the ast has the given symbol */
1621 /*-----------------------------------------------------------------*/
1623 astHasSymbol (ast * tree, symbol * sym)
1625 if (!tree || IS_AST_LINK (tree))
1628 if (IS_AST_VALUE (tree))
1630 if (IS_AST_SYM_VALUE (tree))
1631 return isSymbolEqual (AST_SYMBOL (tree), sym);
1636 return astHasSymbol (tree->left, sym) ||
1637 astHasSymbol (tree->right, sym);
1640 /*-----------------------------------------------------------------*/
1641 /* astHasDeref - return true if the ast has an indirect access */
1642 /*-----------------------------------------------------------------*/
1644 astHasDeref (ast * tree)
1646 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1649 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1651 return astHasDeref (tree->left) || astHasDeref (tree->right);
1654 /*-----------------------------------------------------------------*/
1655 /* isConformingBody - the loop body has to conform to a set of rules */
1656 /* for the loop to be considered reversible read on for rules */
1657 /*-----------------------------------------------------------------*/
1659 isConformingBody (ast * pbody, symbol * sym, ast * body)
1662 /* we are going to do a pre-order traversal of the
1663 tree && check for the following conditions. (essentially
1664 a set of very shallow tests )
1665 a) the sym passed does not participate in
1666 any arithmetic operation
1667 b) There are no function calls
1668 c) all jumps are within the body
1669 d) address of loop control variable not taken
1670 e) if an assignment has a pointer on the
1671 left hand side make sure right does not have
1672 loop control variable */
1674 /* if we reach the end or a leaf then true */
1675 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1678 /* if anything else is "volatile" */
1679 if (IS_VOLATILE (TETYPE (pbody)))
1682 /* we will walk the body in a pre-order traversal for
1684 switch (pbody->opval.op)
1686 /*------------------------------------------------------------------*/
1688 // if the loopvar is used as an index
1689 /* array op is commutative -- must check both left & right */
1690 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1693 return isConformingBody (pbody->right, sym, body)
1694 && isConformingBody (pbody->left, sym, body);
1696 /*------------------------------------------------------------------*/
1701 /*------------------------------------------------------------------*/
1705 /* sure we are not sym is not modified */
1707 IS_AST_SYM_VALUE (pbody->left) &&
1708 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1712 IS_AST_SYM_VALUE (pbody->right) &&
1713 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1718 /*------------------------------------------------------------------*/
1720 case '*': /* can be unary : if right is null then unary operation */
1725 /* if right is NULL then unary operation */
1726 /*------------------------------------------------------------------*/
1727 /*----------------------------*/
1729 /*----------------------------*/
1732 if (IS_AST_SYM_VALUE (pbody->left) &&
1733 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1736 return isConformingBody (pbody->left, sym, body);
1740 if (astHasSymbol (pbody->left, sym) ||
1741 astHasSymbol (pbody->right, sym))
1746 /*------------------------------------------------------------------*/
1754 if (IS_AST_SYM_VALUE (pbody->left) &&
1755 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1758 if (IS_AST_SYM_VALUE (pbody->right) &&
1759 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1762 return isConformingBody (pbody->left, sym, body) &&
1763 isConformingBody (pbody->right, sym, body);
1771 if (IS_AST_SYM_VALUE (pbody->left) &&
1772 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1774 return isConformingBody (pbody->left, sym, body);
1776 /*------------------------------------------------------------------*/
1788 case SIZEOF: /* evaluate wihout code generation */
1790 if (IS_AST_SYM_VALUE (pbody->left) &&
1791 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1794 if (IS_AST_SYM_VALUE (pbody->right) &&
1795 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1798 return isConformingBody (pbody->left, sym, body) &&
1799 isConformingBody (pbody->right, sym, body);
1801 /*------------------------------------------------------------------*/
1804 /* if left has a pointer & right has loop
1805 control variable then we cannot */
1806 if (astHasPointer (pbody->left) &&
1807 astHasSymbol (pbody->right, sym))
1809 if (astHasVolatile (pbody->left))
1812 if (IS_AST_SYM_VALUE (pbody->left)) {
1813 // if the loopvar has an assignment
1814 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1816 // if the loopvar is used in another (maybe conditional) block
1817 if (astHasSymbol (pbody->right, sym) &&
1818 (pbody->level >= body->level)) {
1823 if (astHasVolatile (pbody->left))
1826 if (astHasDeref(pbody->right)) return FALSE;
1828 return isConformingBody (pbody->left, sym, body) &&
1829 isConformingBody (pbody->right, sym, body);
1840 assert ("Parser should not have generated this\n");
1842 /*------------------------------------------------------------------*/
1843 /*----------------------------*/
1844 /* comma operator */
1845 /*----------------------------*/
1847 return isConformingBody (pbody->left, sym, body) &&
1848 isConformingBody (pbody->right, sym, body);
1850 /*------------------------------------------------------------------*/
1851 /*----------------------------*/
1853 /*----------------------------*/
1855 /* if local & not passed as paramater then ok */
1856 if (sym->level && !astHasSymbol(pbody->right,sym))
1860 /*------------------------------------------------------------------*/
1861 /*----------------------------*/
1862 /* return statement */
1863 /*----------------------------*/
1868 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1873 if (astHasSymbol (pbody->left, sym))
1880 return isConformingBody (pbody->left, sym, body) &&
1881 isConformingBody (pbody->right, sym, body);
1887 /*-----------------------------------------------------------------*/
1888 /* isLoopReversible - takes a for loop as input && returns true */
1889 /* if the for loop is reversible. If yes will set the value of */
1890 /* the loop control var & init value & termination value */
1891 /*-----------------------------------------------------------------*/
1893 isLoopReversible (ast * loop, symbol ** loopCntrl,
1894 ast ** init, ast ** end)
1896 /* if option says don't do it then don't */
1897 if (optimize.noLoopReverse)
1899 /* there are several tests to determine this */
1901 /* for loop has to be of the form
1902 for ( <sym> = <const1> ;
1903 [<sym> < <const2>] ;
1904 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1906 if (!isLoopCountable (AST_FOR (loop, initExpr),
1907 AST_FOR (loop, condExpr),
1908 AST_FOR (loop, loopExpr),
1909 loopCntrl, init, end))
1912 /* now do some serious checking on the body of the loop
1915 return isConformingBody (loop->left, *loopCntrl, loop->left);
1919 /*-----------------------------------------------------------------*/
1920 /* replLoopSym - replace the loop sym by loop sym -1 */
1921 /*-----------------------------------------------------------------*/
1923 replLoopSym (ast * body, symbol * sym)
1926 if (!body || IS_AST_LINK (body))
1929 if (IS_AST_SYM_VALUE (body))
1932 if (isSymbolEqual (AST_SYMBOL (body), sym))
1936 body->opval.op = '-';
1937 body->left = newAst_VALUE (symbolVal (sym));
1938 body->right = newAst_VALUE (constVal ("1"));
1946 replLoopSym (body->left, sym);
1947 replLoopSym (body->right, sym);
1951 /*-----------------------------------------------------------------*/
1952 /* reverseLoop - do the actual loop reversal */
1953 /*-----------------------------------------------------------------*/
1955 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1959 /* create the following tree
1964 if (sym) goto for_continue ;
1967 /* put it together piece by piece */
1968 rloop = newNode (NULLOP,
1969 createIf (newAst_VALUE (symbolVal (sym)),
1971 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1974 newAst_VALUE (symbolVal (sym)),
1977 replLoopSym (loop->left, sym);
1978 setAstLineno (rloop, init->lineno);
1980 rloop = newNode (NULLOP,
1982 newAst_VALUE (symbolVal (sym)),
1983 newNode ('-', end, init)),
1984 createLabel (AST_FOR (loop, continueLabel),
1988 newNode (SUB_ASSIGN,
1989 newAst_VALUE (symbolVal (sym)),
1990 newAst_VALUE (constVal ("1"))),
1993 rloop->lineno=init->lineno;
1994 return decorateType (rloop, RESULT_TYPE_NONE);
1998 /*-----------------------------------------------------------------*/
1999 /* searchLitOp - search tree (*ops only) for an ast with literal */
2000 /*-----------------------------------------------------------------*/
2002 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2006 if (tree && optimize.global_cse)
2008 /* is there a literal operand? */
2010 IS_AST_OP(tree->right) &&
2011 tree->right->right &&
2012 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2014 if (IS_LITERAL (RTYPE (tree->right)) !=
2015 IS_LITERAL (LTYPE (tree->right)))
2017 tree->right->decorated = 0;
2018 tree->decorated = 0;
2022 ret = searchLitOp (tree->right, parent, ops);
2027 IS_AST_OP(tree->left) &&
2028 tree->left->right &&
2029 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2031 if (IS_LITERAL (RTYPE (tree->left)) !=
2032 IS_LITERAL (LTYPE (tree->left)))
2034 tree->left->decorated = 0;
2035 tree->decorated = 0;
2039 ret = searchLitOp (tree->left, parent, ops);
2047 /*-----------------------------------------------------------------*/
2048 /* getResultFromType */
2049 /*-----------------------------------------------------------------*/
2051 getResultTypeFromType (sym_link *type)
2053 /* type = getSpec (type); */
2055 return RESULT_TYPE_BIT;
2056 if (IS_BITFIELD (type))
2058 int blen = SPEC_BLEN (type);
2061 return RESULT_TYPE_BIT;
2063 return RESULT_TYPE_CHAR;
2064 return RESULT_TYPE_INT;
2067 return RESULT_TYPE_CHAR;
2070 return RESULT_TYPE_INT;
2071 return RESULT_TYPE_OTHER;
2074 /*-----------------------------------------------------------------*/
2075 /* addCast - adds casts to a type specified by RESULT_TYPE */
2076 /*-----------------------------------------------------------------*/
2078 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2081 bool upCasted = FALSE;
2085 case RESULT_TYPE_NONE:
2086 /* char: promote to int */
2088 getSize (tree->etype) >= INTSIZE)
2090 newLink = newIntLink();
2093 case RESULT_TYPE_CHAR:
2094 if (IS_CHAR (tree->etype) ||
2095 IS_FLOAT(tree->etype))
2097 newLink = newCharLink();
2099 case RESULT_TYPE_INT:
2101 if (getSize (tree->etype) > INTSIZE)
2103 /* warn ("Loosing significant digits"); */
2107 /* char: promote to int */
2109 getSize (tree->etype) >= INTSIZE)
2111 newLink = newIntLink();
2114 case RESULT_TYPE_OTHER:
2117 /* return type is long, float: promote char to int */
2118 if (getSize (tree->etype) >= INTSIZE)
2120 newLink = newIntLink();
2126 tree->decorated = 0;
2127 tree = newNode (CAST, newAst_LINK (newLink), tree);
2128 tree->lineno = tree->right->lineno;
2129 /* keep unsigned type during cast to smaller type,
2130 but not when promoting from char to int */
2132 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2133 return decorateType (tree, resultType);
2136 /*-----------------------------------------------------------------*/
2137 /* resultTypePropagate - decides if resultType can be propagated */
2138 /*-----------------------------------------------------------------*/
2140 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2142 switch (tree->opval.op)
2158 return RESULT_TYPE_NONE;
2162 return RESULT_TYPE_IFX;
2164 return RESULT_TYPE_NONE;
2168 /*-----------------------------------------------------------------*/
2169 /* getLeftResultType - gets type from left branch for propagation */
2170 /*-----------------------------------------------------------------*/
2172 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2174 switch (tree->opval.op)
2178 if (IS_PTR (LTYPE (tree)))
2179 return RESULT_TYPE_NONE;
2181 return getResultTypeFromType (LETYPE (tree));
2183 if (IS_PTR (currFunc->type->next))
2184 return RESULT_TYPE_NONE;
2186 return getResultTypeFromType (currFunc->type->next);
2188 if (!IS_ARRAY (LTYPE (tree)))
2190 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2191 return RESULT_TYPE_CHAR;
2198 /*--------------------------------------------------------------------*/
2199 /* decorateType - compute type for this tree, also does type checking.*/
2200 /* This is done bottom up, since type has to flow upwards. */
2201 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2202 /* result is a char and the operand(s) are int's. */
2203 /* It also does constant folding, and parameter checking. */
2204 /*--------------------------------------------------------------------*/
2206 decorateType (ast * tree, RESULT_TYPE resultType)
2210 RESULT_TYPE resultTypeProp;
2215 /* if already has type then do nothing */
2216 if (tree->decorated)
2219 tree->decorated = 1;
2222 /* print the line */
2223 /* if not block & function */
2224 if (tree->type == EX_OP &&
2225 (tree->opval.op != FUNCTION &&
2226 tree->opval.op != BLOCK &&
2227 tree->opval.op != NULLOP))
2229 filename = tree->filename;
2230 lineno = tree->lineno;
2234 /* if any child is an error | this one is an error do nothing */
2235 if (tree->isError ||
2236 (tree->left && tree->left->isError) ||
2237 (tree->right && tree->right->isError))
2240 /*------------------------------------------------------------------*/
2241 /*----------------------------*/
2242 /* leaf has been reached */
2243 /*----------------------------*/
2244 lineno=tree->lineno;
2245 /* if this is of type value */
2246 /* just get the type */
2247 if (tree->type == EX_VALUE)
2250 if (IS_LITERAL (tree->opval.val->etype))
2253 /* if this is a character array then declare it */
2254 if (IS_ARRAY (tree->opval.val->type))
2255 tree->opval.val = stringToSymbol (tree->opval.val);
2257 /* otherwise just copy the type information */
2258 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2262 if (tree->opval.val->sym)
2264 /* if the undefined flag is set then give error message */
2265 if (tree->opval.val->sym->undefined)
2267 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2269 TTYPE (tree) = TETYPE (tree) =
2270 tree->opval.val->type = tree->opval.val->sym->type =
2271 tree->opval.val->etype = tree->opval.val->sym->etype =
2272 copyLinkChain (INTTYPE);
2277 /* if impilicit i.e. struct/union member then no type */
2278 if (tree->opval.val->sym->implicit)
2279 TTYPE (tree) = TETYPE (tree) = NULL;
2284 /* else copy the type */
2285 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2287 /* and mark it as referenced */
2288 tree->opval.val->sym->isref = 1;
2296 /* if type link for the case of cast */
2297 if (tree->type == EX_LINK)
2299 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2307 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2309 if (tree->left && tree->left->type == EX_OPERAND
2310 && (tree->left->opval.op == INC_OP
2311 || tree->left->opval.op == DEC_OP)
2312 && tree->left->left)
2314 tree->left->right = tree->left->left;
2315 tree->left->left = NULL;
2317 if (tree->right && tree->right->type == EX_OPERAND
2318 && (tree->right->opval.op == INC_OP
2319 || tree->right->opval.op == DEC_OP)
2320 && tree->right->left)
2322 tree->right->right = tree->right->left;
2323 tree->right->left = NULL;
2328 /* Before decorating the left branch we've to decide in dependence
2329 upon tree->opval.op, if resultType can be propagated */
2330 resultTypeProp = resultTypePropagate (tree, resultType);
2332 if (tree->opval.op == '?')
2333 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2335 dtl = decorateType (tree->left, resultTypeProp);
2337 /* if an array node, we may need to swap branches */
2338 if (tree->opval.op == '[')
2340 /* determine which is the array & which the index */
2341 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2342 IS_INTEGRAL (LTYPE (tree)))
2344 ast *tempTree = tree->left;
2345 tree->left = tree->right;
2346 tree->right = tempTree;
2350 /* After decorating the left branch there's type information available
2351 in tree->left->?type. If the op is e.g. '=' we extract the type
2352 information from there and propagate it to the right branch. */
2353 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2355 switch (tree->opval.op)
2358 /* delay right side for '?' operator since conditional macro
2359 expansions might rely on this */
2363 /* decorate right side for CALL (parameter list) in processParms();
2364 there is resultType available */
2368 dtr = decorateType (tree->right, resultTypeProp);
2372 /* this is to take care of situations
2373 when the tree gets rewritten */
2374 if (dtl != tree->left)
2376 if (dtr != tree->right)
2378 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2382 /* depending on type of operator do */
2384 switch (tree->opval.op)
2386 /*------------------------------------------------------------------*/
2387 /*----------------------------*/
2389 /*----------------------------*/
2392 /* first check if this is a array or a pointer */
2393 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2395 werror (E_NEED_ARRAY_PTR, "[]");
2396 goto errorTreeReturn;
2399 /* check if the type of the idx */
2400 if (!IS_INTEGRAL (RTYPE (tree)))
2402 werror (E_IDX_NOT_INT);
2403 goto errorTreeReturn;
2406 /* if the left is an rvalue then error */
2409 werror (E_LVALUE_REQUIRED, "array access");
2410 goto errorTreeReturn;
2413 if (IS_LITERAL (RTYPE (tree)))
2415 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2416 int arraySize = DCL_ELEM (LTYPE (tree));
2417 if (arraySize && arrayIndex >= arraySize)
2419 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2424 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2427 /*------------------------------------------------------------------*/
2428 /*----------------------------*/
2430 /*----------------------------*/
2432 /* if this is not a structure */
2433 if (!IS_STRUCT (LTYPE (tree)))
2435 werror (E_STRUCT_UNION, ".");
2436 goto errorTreeReturn;
2438 TTYPE (tree) = structElemType (LTYPE (tree),
2439 (tree->right->type == EX_VALUE ?
2440 tree->right->opval.val : NULL));
2441 TETYPE (tree) = getSpec (TTYPE (tree));
2444 /*------------------------------------------------------------------*/
2445 /*----------------------------*/
2446 /* struct/union pointer */
2447 /*----------------------------*/
2449 /* if not pointer to a structure */
2450 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2452 werror (E_PTR_REQD);
2453 goto errorTreeReturn;
2456 if (!IS_STRUCT (LTYPE (tree)->next))
2458 werror (E_STRUCT_UNION, "->");
2459 goto errorTreeReturn;
2462 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2463 (tree->right->type == EX_VALUE ?
2464 tree->right->opval.val : NULL));
2465 TETYPE (tree) = getSpec (TTYPE (tree));
2467 /* adjust the storage class */
2468 switch (DCL_TYPE(tree->left->ftype)) {
2470 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2473 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2476 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2479 SPEC_SCLS (TETYPE (tree)) = 0;
2482 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2485 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2488 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2491 SPEC_SCLS (TETYPE (tree)) = 0;
2498 /* This breaks with extern declarations, bitfields, and perhaps other */
2499 /* cases (gcse). Let's leave this optimization disabled for now and */
2500 /* ponder if there's a safe way to do this. -- EEP */
2502 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2503 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2505 /* If defined struct type at addr var
2506 then rewrite (&struct var)->member
2508 and define membertype at (addr+offsetof(struct var,member)) temp
2511 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2512 AST_SYMBOL(tree->right));
2514 sym = newSymbol(genSymName (0), 0);
2515 sym->type = TTYPE (tree);
2516 sym->etype = getSpec(sym->type);
2517 sym->lineDef = tree->lineno;
2520 SPEC_STAT (sym->etype) = 1;
2521 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2523 SPEC_ABSA(sym->etype) = 1;
2524 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2527 AST_VALUE (tree) = symbolVal(sym);
2530 tree->type = EX_VALUE;
2538 /*------------------------------------------------------------------*/
2539 /*----------------------------*/
2540 /* ++/-- operation */
2541 /*----------------------------*/
2545 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2546 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2547 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2548 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2557 /*------------------------------------------------------------------*/
2558 /*----------------------------*/
2560 /*----------------------------*/
2561 case '&': /* can be unary */
2562 /* if right is NULL then unary operation */
2563 if (tree->right) /* not an unary operation */
2566 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2568 werror (E_BITWISE_OP);
2569 werror (W_CONTINUE, "left & right types are ");
2570 printTypeChain (LTYPE (tree), stderr);
2571 fprintf (stderr, ",");
2572 printTypeChain (RTYPE (tree), stderr);
2573 fprintf (stderr, "\n");
2574 goto errorTreeReturn;
2577 /* if they are both literal */
2578 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2580 tree->type = EX_VALUE;
2581 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2582 valFromType (RETYPE (tree)), '&');
2584 tree->right = tree->left = NULL;
2585 TETYPE (tree) = tree->opval.val->etype;
2586 TTYPE (tree) = tree->opval.val->type;
2590 /* see if this is a GETHBIT operation if yes
2593 ast *otree = optimizeGetHbit (tree);
2596 return decorateType (otree, RESULT_TYPE_NONE);
2599 /* if left is a literal exchange left & right */
2600 if (IS_LITERAL (LTYPE (tree)))
2602 ast *tTree = tree->left;
2603 tree->left = tree->right;
2604 tree->right = tTree;
2607 /* if right is a literal and */
2608 /* we can find a 2nd literal in an and-tree then */
2609 /* rearrange the tree */
2610 if (IS_LITERAL (RTYPE (tree)))
2613 ast *litTree = searchLitOp (tree, &parent, "&");
2617 ast *tTree = litTree->left;
2618 litTree->left = tree->right;
2619 tree->right = tTree;
2620 /* both operands in litTree are literal now */
2621 decorateType (parent, resultType);
2625 LRVAL (tree) = RRVAL (tree) = 1;
2627 TTYPE (tree) = computeType (LTYPE (tree),
2631 TETYPE (tree) = getSpec (TTYPE (tree));
2636 /*------------------------------------------------------------------*/
2637 /*----------------------------*/
2639 /*----------------------------*/
2640 p = newLink (DECLARATOR);
2641 /* if bit field then error */
2642 if (IS_BITVAR (tree->left->etype))
2644 werror (E_ILLEGAL_ADDR, "address of bit variable");
2645 goto errorTreeReturn;
2648 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2650 werror (E_ILLEGAL_ADDR, "address of register variable");
2651 goto errorTreeReturn;
2654 if (IS_FUNC (LTYPE (tree)))
2656 // this ought to be ignored
2657 return (tree->left);
2660 if (IS_LITERAL(LTYPE(tree)))
2662 werror (E_ILLEGAL_ADDR, "address of literal");
2663 goto errorTreeReturn;
2668 werror (E_LVALUE_REQUIRED, "address of");
2669 goto errorTreeReturn;
2672 DCL_TYPE (p) = POINTER;
2673 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2674 DCL_TYPE (p) = CPOINTER;
2675 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2676 DCL_TYPE (p) = FPOINTER;
2677 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2678 DCL_TYPE (p) = PPOINTER;
2679 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2680 DCL_TYPE (p) = IPOINTER;
2681 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2682 DCL_TYPE (p) = EEPPOINTER;
2683 else if (SPEC_OCLS(tree->left->etype))
2684 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2686 DCL_TYPE (p) = POINTER;
2688 if (IS_AST_SYM_VALUE (tree->left))
2690 AST_SYMBOL (tree->left)->addrtaken = 1;
2691 AST_SYMBOL (tree->left)->allocreq = 1;
2694 p->next = LTYPE (tree);
2696 TETYPE (tree) = getSpec (TTYPE (tree));
2701 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2702 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2704 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2705 AST_SYMBOL(tree->left->right));
2706 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2707 valueFromLit(element->offset));
2710 tree->type = EX_VALUE;
2711 tree->values.literalFromCast = 1;
2717 /*------------------------------------------------------------------*/
2718 /*----------------------------*/
2720 /*----------------------------*/
2722 /* if the rewrite succeeds then don't go any furthur */
2724 ast *wtree = optimizeRRCRLC (tree);
2726 return decorateType (wtree, RESULT_TYPE_NONE);
2728 wtree = optimizeSWAP (tree);
2730 return decorateType (wtree, RESULT_TYPE_NONE);
2733 /* if left is a literal exchange left & right */
2734 if (IS_LITERAL (LTYPE (tree)))
2736 ast *tTree = tree->left;
2737 tree->left = tree->right;
2738 tree->right = tTree;
2741 /* if right is a literal and */
2742 /* we can find a 2nd literal in an or-tree then */
2743 /* rearrange the tree */
2744 if (IS_LITERAL (RTYPE (tree)))
2747 ast *litTree = searchLitOp (tree, &parent, "|");
2751 ast *tTree = litTree->left;
2752 litTree->left = tree->right;
2753 tree->right = tTree;
2754 /* both operands in tTree are literal now */
2755 decorateType (parent, resultType);
2760 /*------------------------------------------------------------------*/
2761 /*----------------------------*/
2763 /*----------------------------*/
2765 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2767 werror (E_BITWISE_OP);
2768 werror (W_CONTINUE, "left & right types are ");
2769 printTypeChain (LTYPE (tree), stderr);
2770 fprintf (stderr, ",");
2771 printTypeChain (RTYPE (tree), stderr);
2772 fprintf (stderr, "\n");
2773 goto errorTreeReturn;
2776 /* if they are both literal then rewrite the tree */
2777 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2779 tree->type = EX_VALUE;
2780 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2781 valFromType (RETYPE (tree)),
2783 tree->right = tree->left = NULL;
2784 TETYPE (tree) = tree->opval.val->etype;
2785 TTYPE (tree) = tree->opval.val->type;
2789 /* if left is a literal exchange left & right */
2790 if (IS_LITERAL (LTYPE (tree)))
2792 ast *tTree = tree->left;
2793 tree->left = tree->right;
2794 tree->right = tTree;
2797 /* if right is a literal and */
2798 /* we can find a 2nd literal in a xor-tree then */
2799 /* rearrange the tree */
2800 if (IS_LITERAL (RTYPE (tree)) &&
2801 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2804 ast *litTree = searchLitOp (tree, &parent, "^");
2808 ast *tTree = litTree->left;
2809 litTree->left = tree->right;
2810 tree->right = tTree;
2811 /* both operands in litTree are literal now */
2812 decorateType (parent, resultType);
2816 LRVAL (tree) = RRVAL (tree) = 1;
2818 TTYPE (tree) = computeType (LTYPE (tree),
2822 TETYPE (tree) = getSpec (TTYPE (tree));
2826 /*------------------------------------------------------------------*/
2827 /*----------------------------*/
2829 /*----------------------------*/
2831 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2833 werror (E_INVALID_OP, "divide");
2834 goto errorTreeReturn;
2836 /* if they are both literal then */
2837 /* rewrite the tree */
2838 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2840 tree->type = EX_VALUE;
2841 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2842 valFromType (RETYPE (tree)));
2843 tree->right = tree->left = NULL;
2844 TETYPE (tree) = getSpec (TTYPE (tree) =
2845 tree->opval.val->type);
2849 LRVAL (tree) = RRVAL (tree) = 1;
2851 TETYPE (tree) = getSpec (TTYPE (tree) =
2852 computeType (LTYPE (tree),
2857 /* if right is a literal and */
2858 /* left is also a division by a literal then */
2859 /* rearrange the tree */
2860 if (IS_LITERAL (RTYPE (tree))
2861 /* avoid infinite loop */
2862 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2865 ast *litTree = searchLitOp (tree, &parent, "/");
2868 if (IS_LITERAL (RTYPE (litTree)))
2872 litTree->right = newNode ('*',
2874 copyAst (tree->right));
2875 litTree->right->lineno = tree->lineno;
2877 tree->right->opval.val = constVal ("1");
2878 decorateType (parent, resultType);
2882 /* litTree->left is literal: no gcse possible.
2883 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2884 this would cause an infinit loop. */
2885 parent->decorated = 1;
2886 decorateType (litTree, resultType);
2893 /*------------------------------------------------------------------*/
2894 /*----------------------------*/
2896 /*----------------------------*/
2898 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2900 werror (E_BITWISE_OP);
2901 werror (W_CONTINUE, "left & right types are ");
2902 printTypeChain (LTYPE (tree), stderr);
2903 fprintf (stderr, ",");
2904 printTypeChain (RTYPE (tree), stderr);
2905 fprintf (stderr, "\n");
2906 goto errorTreeReturn;
2908 /* if they are both literal then */
2909 /* rewrite the tree */
2910 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2912 tree->type = EX_VALUE;
2913 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2914 valFromType (RETYPE (tree)));
2915 tree->right = tree->left = NULL;
2916 TETYPE (tree) = getSpec (TTYPE (tree) =
2917 tree->opval.val->type);
2920 LRVAL (tree) = RRVAL (tree) = 1;
2921 TETYPE (tree) = getSpec (TTYPE (tree) =
2922 computeType (LTYPE (tree),
2928 /*------------------------------------------------------------------*/
2929 /*----------------------------*/
2930 /* address dereference */
2931 /*----------------------------*/
2932 case '*': /* can be unary : if right is null then unary operation */
2935 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2937 werror (E_PTR_REQD);
2938 goto errorTreeReturn;
2943 werror (E_LVALUE_REQUIRED, "pointer deref");
2944 goto errorTreeReturn;
2946 if (IS_ADDRESS_OF_OP(tree->left))
2948 /* replace *&obj with obj */
2949 return tree->left->left;
2951 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2952 TETYPE (tree) = getSpec (TTYPE (tree));
2953 /* adjust the storage class */
2954 switch (DCL_TYPE(tree->left->ftype)) {
2956 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2959 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2962 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2965 SPEC_SCLS (TETYPE (tree)) = 0;
2968 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2971 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2974 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2977 SPEC_SCLS (TETYPE (tree)) = 0;
2986 /*------------------------------------------------------------------*/
2987 /*----------------------------*/
2988 /* multiplication */
2989 /*----------------------------*/
2990 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2992 werror (E_INVALID_OP, "multiplication");
2993 goto errorTreeReturn;
2996 /* if they are both literal then */
2997 /* rewrite the tree */
2998 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3000 tree->type = EX_VALUE;
3001 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3002 valFromType (RETYPE (tree)));
3003 tree->right = tree->left = NULL;
3004 TETYPE (tree) = getSpec (TTYPE (tree) =
3005 tree->opval.val->type);
3009 /* if left is a literal exchange left & right */
3010 if (IS_LITERAL (LTYPE (tree)))
3012 ast *tTree = tree->left;
3013 tree->left = tree->right;
3014 tree->right = tTree;
3017 /* if right is a literal and */
3018 /* we can find a 2nd literal in a mul-tree then */
3019 /* rearrange the tree */
3020 if (IS_LITERAL (RTYPE (tree)))
3023 ast *litTree = searchLitOp (tree, &parent, "*");
3027 ast *tTree = litTree->left;
3028 litTree->left = tree->right;
3029 tree->right = tTree;
3030 /* both operands in litTree are literal now */
3031 decorateType (parent, resultType);
3035 LRVAL (tree) = RRVAL (tree) = 1;
3036 tree->left = addCast (tree->left, resultType, FALSE);
3037 tree->right = addCast (tree->right, resultType, FALSE);
3038 TETYPE (tree) = getSpec (TTYPE (tree) =
3039 computeType (LTYPE (tree),
3046 /*------------------------------------------------------------------*/
3047 /*----------------------------*/
3048 /* unary '+' operator */
3049 /*----------------------------*/
3054 if (!IS_ARITHMETIC (LTYPE (tree)))
3056 werror (E_UNARY_OP, '+');
3057 goto errorTreeReturn;
3060 /* if left is a literal then do it */
3061 if (IS_LITERAL (LTYPE (tree)))
3063 tree->type = EX_VALUE;
3064 tree->opval.val = valFromType (LETYPE (tree));
3066 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3070 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3074 /*------------------------------------------------------------------*/
3075 /*----------------------------*/
3077 /*----------------------------*/
3079 /* this is not a unary operation */
3080 /* if both pointers then problem */
3081 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3082 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3084 werror (E_PTR_PLUS_PTR);
3085 goto errorTreeReturn;
3088 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3089 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3091 werror (E_PLUS_INVALID, "+");
3092 goto errorTreeReturn;
3095 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3096 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3098 werror (E_PLUS_INVALID, "+");
3099 goto errorTreeReturn;
3101 /* if they are both literal then */
3102 /* rewrite the tree */
3103 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3105 tree->type = EX_VALUE;
3106 tree->left = addCast (tree->left, resultType, TRUE);
3107 tree->right = addCast (tree->right, resultType, TRUE);
3108 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3109 valFromType (RETYPE (tree)));
3110 tree->right = tree->left = NULL;
3111 TETYPE (tree) = getSpec (TTYPE (tree) =
3112 tree->opval.val->type);
3116 /* if the right is a pointer or left is a literal
3117 xchange left & right */
3118 if (IS_ARRAY (RTYPE (tree)) ||
3119 IS_PTR (RTYPE (tree)) ||
3120 IS_LITERAL (LTYPE (tree)))
3122 ast *tTree = tree->left;
3123 tree->left = tree->right;
3124 tree->right = tTree;
3127 /* if right is a literal and */
3128 /* left is also an addition/subtraction with a literal then */
3129 /* rearrange the tree */
3130 if (IS_LITERAL (RTYPE (tree)))
3132 ast *litTree, *parent;
3133 litTree = searchLitOp (tree, &parent, "+-");
3136 if (litTree->opval.op == '+')
3140 ast *tTree = litTree->left;
3141 litTree->left = tree->right;
3142 tree->right = tree->left;
3145 else if (litTree->opval.op == '-')
3147 if (IS_LITERAL (RTYPE (litTree)))
3151 ast *tTree = litTree->left;
3152 litTree->left = tree->right;
3153 tree->right = tTree;
3159 ast *tTree = litTree->right;
3160 litTree->right = tree->right;
3161 tree->right = tTree;
3162 litTree->opval.op = '+';
3163 tree->opval.op = '-';
3166 decorateType (parent, resultType);
3170 LRVAL (tree) = RRVAL (tree) = 1;
3171 /* if the left is a pointer */
3172 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3173 TETYPE (tree) = getSpec (TTYPE (tree) =
3177 tree->left = addCast (tree->left, resultType, TRUE);
3178 tree->right = addCast (tree->right, resultType, TRUE);
3179 TETYPE (tree) = getSpec (TTYPE (tree) =
3180 computeType (LTYPE (tree),
3188 /*------------------------------------------------------------------*/
3189 /*----------------------------*/
3191 /*----------------------------*/
3192 case '-': /* can be unary */
3193 /* if right is null then unary */
3197 if (!IS_ARITHMETIC (LTYPE (tree)))
3199 werror (E_UNARY_OP, tree->opval.op);
3200 goto errorTreeReturn;
3203 /* if left is a literal then do it */
3204 if (IS_LITERAL (LTYPE (tree)))
3206 tree->type = EX_VALUE;
3207 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3209 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3210 SPEC_USIGN(TETYPE(tree)) = 0;
3214 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3218 /*------------------------------------------------------------------*/
3219 /*----------------------------*/
3221 /*----------------------------*/
3223 if (!(IS_PTR (LTYPE (tree)) ||
3224 IS_ARRAY (LTYPE (tree)) ||
3225 IS_ARITHMETIC (LTYPE (tree))))
3227 werror (E_PLUS_INVALID, "-");
3228 goto errorTreeReturn;
3231 if (!(IS_PTR (RTYPE (tree)) ||
3232 IS_ARRAY (RTYPE (tree)) ||
3233 IS_ARITHMETIC (RTYPE (tree))))
3235 werror (E_PLUS_INVALID, "-");
3236 goto errorTreeReturn;
3239 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3240 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3241 IS_INTEGRAL (RTYPE (tree))))
3243 werror (E_PLUS_INVALID, "-");
3244 goto errorTreeReturn;
3247 /* if they are both literal then */
3248 /* rewrite the tree */
3249 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3251 tree->type = EX_VALUE;
3252 tree->left = addCast (tree->left, resultType, TRUE);
3253 tree->right = addCast (tree->right, resultType, TRUE);
3254 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3255 valFromType (RETYPE (tree)));
3256 tree->right = tree->left = NULL;
3257 TETYPE (tree) = getSpec (TTYPE (tree) =
3258 tree->opval.val->type);
3262 /* if the left & right are equal then zero */
3263 if (isAstEqual (tree->left, tree->right))
3265 tree->type = EX_VALUE;
3266 tree->left = tree->right = NULL;
3267 tree->opval.val = constVal ("0");
3268 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3272 /* if both of them are pointers or arrays then */
3273 /* the result is going to be an integer */
3274 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3275 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3276 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3278 /* if only the left is a pointer */
3279 /* then result is a pointer */
3280 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3281 TETYPE (tree) = getSpec (TTYPE (tree) =
3285 tree->left = addCast (tree->left, resultType, TRUE);
3286 tree->right = addCast (tree->right, resultType, TRUE);
3288 TETYPE (tree) = getSpec (TTYPE (tree) =
3289 computeType (LTYPE (tree),
3295 LRVAL (tree) = RRVAL (tree) = 1;
3297 /* if right is a literal and */
3298 /* left is also an addition/subtraction with a literal then */
3299 /* rearrange the tree */
3300 if (IS_LITERAL (RTYPE (tree))
3301 /* avoid infinite loop */
3302 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3304 ast *litTree, *litParent;
3305 litTree = searchLitOp (tree, &litParent, "+-");
3308 if (litTree->opval.op == '+')
3312 ast *tTree = litTree->left;
3313 litTree->left = litTree->right;
3314 litTree->right = tree->right;
3315 tree->right = tTree;
3316 tree->opval.op = '+';
3317 litTree->opval.op = '-';
3319 else if (litTree->opval.op == '-')
3321 if (IS_LITERAL (RTYPE (litTree)))
3325 ast *tTree = litTree->left;
3326 litTree->left = tree->right;
3327 tree->right = litParent->left;
3328 litParent->left = tTree;
3329 litTree->opval.op = '+';
3331 tree->decorated = 0;
3332 decorateType (tree, resultType);
3338 ast *tTree = litTree->right;
3339 litTree->right = tree->right;
3340 tree->right = tTree;
3343 decorateType (litParent, resultType);
3348 /*------------------------------------------------------------------*/
3349 /*----------------------------*/
3351 /*----------------------------*/
3353 /* can be only integral type */
3354 if (!IS_INTEGRAL (LTYPE (tree)))
3356 werror (E_UNARY_OP, tree->opval.op);
3357 goto errorTreeReturn;
3360 /* if left is a literal then do it */
3361 if (IS_LITERAL (LTYPE (tree)))
3363 tree->type = EX_VALUE;
3364 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3366 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3367 return addCast (tree, resultType, TRUE);
3369 tree->left = addCast (tree->left, resultType, TRUE);
3371 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3374 /*------------------------------------------------------------------*/
3375 /*----------------------------*/
3377 /*----------------------------*/
3379 /* can be pointer */
3380 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3381 !IS_PTR (LTYPE (tree)) &&
3382 !IS_ARRAY (LTYPE (tree)))
3384 werror (E_UNARY_OP, tree->opval.op);
3385 goto errorTreeReturn;
3388 /* if left is a literal then do it */
3389 if (IS_LITERAL (LTYPE (tree)))
3391 tree->type = EX_VALUE;
3392 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3394 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3398 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3401 /*------------------------------------------------------------------*/
3402 /*----------------------------*/
3404 /*----------------------------*/
3408 TTYPE (tree) = LTYPE (tree);
3409 TETYPE (tree) = LETYPE (tree);
3413 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3418 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3420 werror (E_SHIFT_OP_INVALID);
3421 werror (W_CONTINUE, "left & right types are ");
3422 printTypeChain (LTYPE (tree), stderr);
3423 fprintf (stderr, ",");
3424 printTypeChain (RTYPE (tree), stderr);
3425 fprintf (stderr, "\n");
3426 goto errorTreeReturn;
3429 /* make smaller type only if it's a LEFT_OP */
3430 if (tree->opval.op == LEFT_OP)
3431 tree->left = addCast (tree->left, resultType, TRUE);
3433 /* if they are both literal then */
3434 /* rewrite the tree */
3435 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3437 tree->type = EX_VALUE;
3438 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3439 valFromType (RETYPE (tree)),
3440 (tree->opval.op == LEFT_OP ? 1 : 0));
3441 tree->right = tree->left = NULL;
3442 TETYPE (tree) = getSpec (TTYPE (tree) =
3443 tree->opval.val->type);
3447 LRVAL (tree) = RRVAL (tree) = 1;
3448 if (tree->opval.op == LEFT_OP)
3450 TETYPE (tree) = getSpec (TTYPE (tree) =
3451 computeType (LTYPE (tree),
3458 /* no promotion necessary */
3459 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3460 if (IS_LITERAL (TTYPE (tree)))
3461 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3464 /* if only the right side is a literal & we are
3465 shifting more than size of the left operand then zero */
3466 if (IS_LITERAL (RTYPE (tree)) &&
3467 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3468 (getSize (TETYPE (tree)) * 8))
3470 if (tree->opval.op==LEFT_OP ||
3471 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3473 lineno=tree->lineno;
3474 werror (W_SHIFT_CHANGED,
3475 (tree->opval.op == LEFT_OP ? "left" : "right"));
3476 tree->type = EX_VALUE;
3477 tree->left = tree->right = NULL;
3478 tree->opval.val = constVal ("0");
3479 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3486 /*------------------------------------------------------------------*/
3487 /*----------------------------*/
3489 /*----------------------------*/
3490 case CAST: /* change the type */
3491 /* cannot cast to an aggregate type */
3492 if (IS_AGGREGATE (LTYPE (tree)))
3494 werror (E_CAST_ILLEGAL);
3495 goto errorTreeReturn;
3498 /* make sure the type is complete and sane */
3499 changePointer(LTYPE(tree));
3500 checkTypeSanity(LETYPE(tree), "(cast)");
3502 /* If code memory is read only, then pointers to code memory */
3503 /* implicitly point to constants -- make this explicit */
3505 sym_link *t = LTYPE(tree);
3506 while (t && t->next)
3508 if (IS_CODEPTR(t) && port->mem.code_ro)
3510 if (IS_SPEC(t->next))
3511 SPEC_CONST (t->next) = 1;
3513 DCL_PTR_CONST (t->next) = 1;
3520 /* if the right is a literal replace the tree */
3521 if (IS_LITERAL (RETYPE (tree))) {
3522 if (!IS_PTR (LTYPE (tree))) {
3523 tree->type = EX_VALUE;
3525 valCastLiteral (LTYPE (tree),
3526 floatFromVal (valFromType (RETYPE (tree))));
3529 TTYPE (tree) = tree->opval.val->type;
3530 tree->values.literalFromCast = 1;
3531 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3532 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3533 sym_link *rest = LTYPE(tree)->next;
3534 werror(W_LITERAL_GENERIC);
3535 TTYPE(tree) = newLink(DECLARATOR);
3536 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3537 TTYPE(tree)->next = rest;
3538 tree->left->opval.lnk = TTYPE(tree);
3541 TTYPE (tree) = LTYPE (tree);
3545 TTYPE (tree) = LTYPE (tree);
3549 #if 0 // this is already checked, now this could be explicit
3550 /* if pointer to struct then check names */
3551 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3552 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3553 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3555 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3556 SPEC_STRUCT(LETYPE(tree))->tag);
3559 if (IS_ADDRESS_OF_OP(tree->right)
3560 && IS_AST_SYM_VALUE (tree->right->left)
3561 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3563 tree->type = EX_VALUE;
3565 valCastLiteral (LTYPE (tree),
3566 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3567 TTYPE (tree) = tree->opval.val->type;
3568 TETYPE (tree) = getSpec (TTYPE (tree));
3571 tree->values.literalFromCast = 1;
3575 /* handle offsetof macro: */
3576 /* #define offsetof(TYPE, MEMBER) \ */
3577 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3578 if (IS_ADDRESS_OF_OP(tree->right)
3579 && IS_AST_OP (tree->right->left)
3580 && tree->right->left->opval.op == PTR_OP
3581 && IS_AST_OP (tree->right->left->left)
3582 && tree->right->left->left->opval.op == CAST
3583 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3585 symbol *element = getStructElement (
3586 SPEC_STRUCT (LETYPE(tree->right->left)),
3587 AST_SYMBOL(tree->right->left->right)
3591 tree->type = EX_VALUE;
3592 tree->opval.val = valCastLiteral (
3595 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3598 TTYPE (tree) = tree->opval.val->type;
3599 TETYPE (tree) = getSpec (TTYPE (tree));
3606 /* if the right is a literal replace the tree */
3607 if (IS_LITERAL (RETYPE (tree))) {
3609 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3610 /* rewrite (type *)litaddr
3612 and define type at litaddr temp
3613 (but only if type's storage class is not generic)
3615 ast *newTree = newNode ('&', NULL, NULL);
3618 TTYPE (newTree) = LTYPE (tree);
3619 TETYPE (newTree) = getSpec(LTYPE (tree));
3621 /* define a global symbol at the casted address*/
3622 sym = newSymbol(genSymName (0), 0);
3623 sym->type = LTYPE (tree)->next;
3625 sym->type = newLink (V_VOID);
3626 sym->etype = getSpec(sym->type);
3627 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3628 sym->lineDef = tree->lineno;
3631 SPEC_STAT (sym->etype) = 1;
3632 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3633 SPEC_ABSA(sym->etype) = 1;
3634 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3637 newTree->left = newAst_VALUE(symbolVal(sym));
3638 newTree->left->lineno = tree->lineno;
3639 LTYPE (newTree) = sym->type;
3640 LETYPE (newTree) = sym->etype;
3641 LLVAL (newTree) = 1;
3642 LRVAL (newTree) = 0;
3643 TLVAL (newTree) = 1;
3647 if (!IS_PTR (LTYPE (tree))) {
3648 tree->type = EX_VALUE;
3650 valCastLiteral (LTYPE (tree),
3651 floatFromVal (valFromType (RTYPE (tree))));
3652 TTYPE (tree) = tree->opval.val->type;
3655 tree->values.literalFromCast = 1;
3656 TETYPE (tree) = getSpec (TTYPE (tree));
3660 TTYPE (tree) = LTYPE (tree);
3664 TETYPE (tree) = getSpec (TTYPE (tree));
3668 /*------------------------------------------------------------------*/
3669 /*----------------------------*/
3670 /* logical &&, || */
3671 /*----------------------------*/
3674 /* each must be arithmetic type or be a pointer */
3675 if (!IS_PTR (LTYPE (tree)) &&
3676 !IS_ARRAY (LTYPE (tree)) &&
3677 !IS_INTEGRAL (LTYPE (tree)))
3679 werror (E_COMPARE_OP);
3680 goto errorTreeReturn;
3683 if (!IS_PTR (RTYPE (tree)) &&
3684 !IS_ARRAY (RTYPE (tree)) &&
3685 !IS_INTEGRAL (RTYPE (tree)))
3687 werror (E_COMPARE_OP);
3688 goto errorTreeReturn;
3690 /* if they are both literal then */
3691 /* rewrite the tree */
3692 if (IS_LITERAL (RTYPE (tree)) &&
3693 IS_LITERAL (LTYPE (tree)))
3695 tree->type = EX_VALUE;
3696 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3697 valFromType (RTYPE (tree)),
3699 tree->right = tree->left = NULL;
3700 TETYPE (tree) = getSpec (TTYPE (tree) =
3701 tree->opval.val->type);
3704 LRVAL (tree) = RRVAL (tree) = 1;
3705 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3708 /*------------------------------------------------------------------*/
3709 /*----------------------------*/
3710 /* comparison operators */
3711 /*----------------------------*/
3719 ast *lt = optimizeCompare (tree);
3725 /* if they are pointers they must be castable */
3726 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3728 if (tree->opval.op==EQ_OP &&
3729 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3730 // we cannot cast a gptr to a !gptr: switch the leaves
3731 struct ast *s=tree->left;
3732 tree->left=tree->right;
3735 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3737 werror (E_COMPARE_OP);
3738 fprintf (stderr, "comparing type ");
3739 printTypeChain (LTYPE (tree), stderr);
3740 fprintf (stderr, "to type ");
3741 printTypeChain (RTYPE (tree), stderr);
3742 fprintf (stderr, "\n");
3743 goto errorTreeReturn;
3746 /* else they should be promotable to one another */
3749 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3750 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3752 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3754 werror (E_COMPARE_OP);
3755 fprintf (stderr, "comparing type ");
3756 printTypeChain (LTYPE (tree), stderr);
3757 fprintf (stderr, "to type ");
3758 printTypeChain (RTYPE (tree), stderr);
3759 fprintf (stderr, "\n");
3760 goto errorTreeReturn;
3763 /* if unsigned value < 0 then always false */
3764 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3765 if (SPEC_USIGN(LETYPE(tree)) &&
3766 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3767 IS_LITERAL(RTYPE(tree)) &&
3768 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3770 if (tree->opval.op == '<')
3774 if (tree->opval.op == '>')
3776 if (resultType == RESULT_TYPE_IFX)
3778 /* the parent is an ifx: */
3779 /* if (unsigned value) */
3783 /* (unsigned value) ? 1 : 0 */
3784 tree->opval.op = '?';
3785 tree->right = newNode (':',
3786 newAst_VALUE (constVal ("1")),
3787 tree->right); /* val 0 */
3788 tree->right->lineno = tree->lineno;
3789 tree->right->left->lineno = tree->lineno;
3790 decorateType (tree->right, RESULT_TYPE_NONE);
3793 /* if they are both literal then */
3794 /* rewrite the tree */
3795 if (IS_LITERAL (RTYPE (tree)) &&
3796 IS_LITERAL (LTYPE (tree)))
3798 tree->type = EX_VALUE;
3799 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3800 valFromType (RETYPE (tree)),
3802 tree->right = tree->left = NULL;
3803 TETYPE (tree) = getSpec (TTYPE (tree) =
3804 tree->opval.val->type);
3807 LRVAL (tree) = RRVAL (tree) = 1;
3808 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3811 /*------------------------------------------------------------------*/
3812 /*----------------------------*/
3814 /*----------------------------*/
3815 case SIZEOF: /* evaluate wihout code generation */
3816 /* change the type to a integer */
3818 int size = getSize (tree->right->ftype);
3819 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3820 if (!size && !IS_VOID(tree->right->ftype))
3821 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3823 tree->type = EX_VALUE;
3824 tree->opval.val = constVal (buffer);
3825 tree->right = tree->left = NULL;
3826 TETYPE (tree) = getSpec (TTYPE (tree) =
3827 tree->opval.val->type);
3830 /*------------------------------------------------------------------*/
3831 /*----------------------------*/
3833 /*----------------------------*/
3835 /* return typeof enum value */
3836 tree->type = EX_VALUE;
3839 if (IS_SPEC(tree->right->ftype)) {
3840 switch (SPEC_NOUN(tree->right->ftype)) {
3842 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3843 else typeofv = TYPEOF_INT;
3846 typeofv = TYPEOF_FLOAT;
3849 typeofv = TYPEOF_CHAR;
3852 typeofv = TYPEOF_VOID;
3855 typeofv = TYPEOF_STRUCT;
3858 typeofv = TYPEOF_BITFIELD;
3861 typeofv = TYPEOF_BIT;
3864 typeofv = TYPEOF_SBIT;
3870 switch (DCL_TYPE(tree->right->ftype)) {
3872 typeofv = TYPEOF_POINTER;
3875 typeofv = TYPEOF_FPOINTER;
3878 typeofv = TYPEOF_CPOINTER;
3881 typeofv = TYPEOF_GPOINTER;
3884 typeofv = TYPEOF_PPOINTER;
3887 typeofv = TYPEOF_IPOINTER;
3890 typeofv = TYPEOF_ARRAY;
3893 typeofv = TYPEOF_FUNCTION;
3899 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3900 tree->opval.val = constVal (buffer);
3901 tree->right = tree->left = NULL;
3902 TETYPE (tree) = getSpec (TTYPE (tree) =
3903 tree->opval.val->type);
3906 /*------------------------------------------------------------------*/
3907 /*----------------------------*/
3908 /* conditional operator '?' */
3909 /*----------------------------*/
3911 /* the type is value of the colon operator (on the right) */
3912 assert (IS_COLON_OP (tree->right));
3913 /* if already known then replace the tree : optimizer will do it
3914 but faster to do it here */
3915 if (IS_LITERAL (LTYPE (tree)))
3917 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3918 return decorateType (tree->right->left, resultTypeProp);
3920 return decorateType (tree->right->right, resultTypeProp);
3924 tree->right = decorateType (tree->right, resultTypeProp);
3925 TTYPE (tree) = RTYPE (tree);
3926 TETYPE (tree) = getSpec (TTYPE (tree));
3931 /* if they don't match we have a problem */
3932 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3934 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3935 goto errorTreeReturn;
3938 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3939 resultType, tree->opval.op);
3940 TETYPE (tree) = getSpec (TTYPE (tree));
3944 #if 0 // assignment operators are converted by the parser
3945 /*------------------------------------------------------------------*/
3946 /*----------------------------*/
3947 /* assignment operators */
3948 /*----------------------------*/
3951 /* for these it must be both must be integral */
3952 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3953 !IS_ARITHMETIC (RTYPE (tree)))
3955 werror (E_OPS_INTEGRAL);
3956 goto errorTreeReturn;
3959 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3961 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3962 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3966 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3967 goto errorTreeReturn;
3978 /* for these it must be both must be integral */
3979 if (!IS_INTEGRAL (LTYPE (tree)) ||
3980 !IS_INTEGRAL (RTYPE (tree)))
3982 werror (E_OPS_INTEGRAL);
3983 goto errorTreeReturn;
3986 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3988 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3989 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3993 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3994 goto errorTreeReturn;
4000 /*------------------------------------------------------------------*/
4001 /*----------------------------*/
4003 /*----------------------------*/
4005 if (!(IS_PTR (LTYPE (tree)) ||
4006 IS_ARITHMETIC (LTYPE (tree))))
4008 werror (E_PLUS_INVALID, "-=");
4009 goto errorTreeReturn;
4012 if (!(IS_PTR (RTYPE (tree)) ||
4013 IS_ARITHMETIC (RTYPE (tree))))
4015 werror (E_PLUS_INVALID, "-=");
4016 goto errorTreeReturn;
4019 TETYPE (tree) = getSpec (TTYPE (tree) =
4020 computeType (LTYPE (tree),
4025 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4026 werror (E_CODE_WRITE, "-=");
4030 werror (E_LVALUE_REQUIRED, "-=");
4031 goto errorTreeReturn;
4037 /*------------------------------------------------------------------*/
4038 /*----------------------------*/
4040 /*----------------------------*/
4042 /* this is not a unary operation */
4043 /* if both pointers then problem */
4044 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4046 werror (E_PTR_PLUS_PTR);
4047 goto errorTreeReturn;
4050 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4052 werror (E_PLUS_INVALID, "+=");
4053 goto errorTreeReturn;
4056 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4058 werror (E_PLUS_INVALID, "+=");
4059 goto errorTreeReturn;
4062 TETYPE (tree) = getSpec (TTYPE (tree) =
4063 computeType (LTYPE (tree),
4068 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4069 werror (E_CODE_WRITE, "+=");
4073 werror (E_LVALUE_REQUIRED, "+=");
4074 goto errorTreeReturn;
4077 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4078 tree->opval.op = '=';
4083 /*------------------------------------------------------------------*/
4084 /*----------------------------*/
4085 /* straight assignemnt */
4086 /*----------------------------*/
4088 /* cannot be an aggregate */
4089 if (IS_AGGREGATE (LTYPE (tree)))
4091 werror (E_AGGR_ASSIGN);
4092 goto errorTreeReturn;
4095 /* they should either match or be castable */
4096 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4098 werror (E_TYPE_MISMATCH, "assignment", " ");
4099 printFromToType(RTYPE(tree),LTYPE(tree));
4102 /* if the left side of the tree is of type void
4103 then report error */
4104 if (IS_VOID (LTYPE (tree)))
4106 werror (E_CAST_ZERO);
4107 printFromToType(RTYPE(tree), LTYPE(tree));
4110 TETYPE (tree) = getSpec (TTYPE (tree) =
4114 if (!tree->initMode ) {
4115 if (IS_CONSTANT(LTYPE(tree)))
4116 werror (E_CODE_WRITE, "=");
4120 werror (E_LVALUE_REQUIRED, "=");
4121 goto errorTreeReturn;
4126 /*------------------------------------------------------------------*/
4127 /*----------------------------*/
4128 /* comma operator */
4129 /*----------------------------*/
4131 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4134 /*------------------------------------------------------------------*/
4135 /*----------------------------*/
4137 /*----------------------------*/
4140 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4141 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4143 if (tree->left->opval.op == '*' && !tree->left->right)
4144 tree->left = tree->left->left;
4147 /* require a function or pointer to function */
4148 if (!IS_FUNC (LTYPE (tree))
4149 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4151 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4152 goto errorTreeReturn;
4155 /* if there are parms, make sure that
4156 parms are decorate / process / reverse only once */
4158 !tree->right->decorated)
4163 if (IS_CODEPTR(LTYPE(tree)))
4164 functype = LTYPE (tree)->next;
4166 functype = LTYPE (tree);
4168 if (processParms (tree->left, FUNC_ARGS(functype),
4169 &tree->right, &parmNumber, TRUE))
4171 goto errorTreeReturn;
4174 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4175 !IFFUNC_ISBUILTIN(functype))
4177 reverseParms (tree->right);
4180 TTYPE (tree) = functype->next;
4181 TETYPE (tree) = getSpec (TTYPE (tree));
4185 /*------------------------------------------------------------------*/
4186 /*----------------------------*/
4187 /* return statement */
4188 /*----------------------------*/
4193 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4195 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4196 printFromToType (RTYPE(tree), currFunc->type->next);
4197 goto errorTreeReturn;
4200 if (IS_VOID (currFunc->type->next)
4202 !IS_VOID (RTYPE (tree)))
4204 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4205 goto errorTreeReturn;
4208 /* if there is going to be a casting required then add it */
4209 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4212 decorateType (newNode (CAST,
4213 newAst_LINK (copyLinkChain (currFunc->type->next)),
4223 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4225 werror (W_VOID_FUNC, currFunc->name);
4226 goto errorTreeReturn;
4229 TTYPE (tree) = TETYPE (tree) = NULL;
4232 /*------------------------------------------------------------------*/
4233 /*----------------------------*/
4234 /* switch statement */
4235 /*----------------------------*/
4237 /* the switch value must be an integer */
4238 if (!IS_INTEGRAL (LTYPE (tree)))
4240 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4241 goto errorTreeReturn;
4244 TTYPE (tree) = TETYPE (tree) = NULL;
4247 /*------------------------------------------------------------------*/
4248 /*----------------------------*/
4250 /*----------------------------*/
4252 tree->left = backPatchLabels (tree->left,
4255 TTYPE (tree) = TETYPE (tree) = NULL;
4258 /*------------------------------------------------------------------*/
4259 /*----------------------------*/
4261 /*----------------------------*/
4264 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4265 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4266 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4268 /* if the for loop is reversible then
4269 reverse it otherwise do what we normally
4275 if (isLoopReversible (tree, &sym, &init, &end))
4276 return reverseLoop (tree, sym, init, end);
4278 return decorateType (createFor (AST_FOR (tree, trueLabel),
4279 AST_FOR (tree, continueLabel),
4280 AST_FOR (tree, falseLabel),
4281 AST_FOR (tree, condLabel),
4282 AST_FOR (tree, initExpr),
4283 AST_FOR (tree, condExpr),
4284 AST_FOR (tree, loopExpr),
4285 tree->left), RESULT_TYPE_NONE);
4288 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4289 "node PARAM shouldn't be processed here");
4290 /* but in processParams() */
4293 TTYPE (tree) = TETYPE (tree) = NULL;
4297 /* some error found this tree will be killed */
4299 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4300 tree->opval.op = NULLOP;
4306 /*-----------------------------------------------------------------*/
4307 /* sizeofOp - processes size of operation */
4308 /*-----------------------------------------------------------------*/
4310 sizeofOp (sym_link * type)
4315 /* make sure the type is complete and sane */
4316 checkTypeSanity(type, "(sizeof)");
4318 /* get the size and convert it to character */
4319 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4320 if (!size && !IS_VOID(type))
4321 werror (E_SIZEOF_INCOMPLETE_TYPE);
4323 /* now convert into value */
4324 return constVal (buff);
4328 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4329 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4330 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4331 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4332 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4333 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4334 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4336 /*-----------------------------------------------------------------*/
4337 /* backPatchLabels - change and or not operators to flow control */
4338 /*-----------------------------------------------------------------*/
4340 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4346 if (!(IS_ANDORNOT (tree)))
4349 /* if this an and */
4352 static int localLbl = 0;
4355 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4356 localLabel = newSymbol (buffer, NestLevel);
4358 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4360 /* if left is already a IFX then just change the if true label in that */
4361 if (!IS_IFX (tree->left))
4362 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4364 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4365 /* right is a IFX then just join */
4366 if (IS_IFX (tree->right))
4367 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4369 tree->right = createLabel (localLabel, tree->right);
4370 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4372 return newNode (NULLOP, tree->left, tree->right);
4375 /* if this is an or operation */
4378 static int localLbl = 0;
4381 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4382 localLabel = newSymbol (buffer, NestLevel);
4384 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4386 /* if left is already a IFX then just change the if true label in that */
4387 if (!IS_IFX (tree->left))
4388 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4390 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4391 /* right is a IFX then just join */
4392 if (IS_IFX (tree->right))
4393 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4395 tree->right = createLabel (localLabel, tree->right);
4396 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4398 return newNode (NULLOP, tree->left, tree->right);
4404 int wasnot = IS_NOT (tree->left);
4405 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4407 /* if the left is already a IFX */
4408 if (!IS_IFX (tree->left))
4409 tree->left = newNode (IFX, tree->left, NULL);
4413 tree->left->trueLabel = trueLabel;
4414 tree->left->falseLabel = falseLabel;
4418 tree->left->trueLabel = falseLabel;
4419 tree->left->falseLabel = trueLabel;
4426 tree->trueLabel = trueLabel;
4427 tree->falseLabel = falseLabel;
4434 /*-----------------------------------------------------------------*/
4435 /* createBlock - create expression tree for block */
4436 /*-----------------------------------------------------------------*/
4438 createBlock (symbol * decl, ast * body)
4442 /* if the block has nothing */
4446 ex = newNode (BLOCK, NULL, body);
4447 ex->values.sym = decl;
4454 /*-----------------------------------------------------------------*/
4455 /* createLabel - creates the expression tree for labels */
4456 /*-----------------------------------------------------------------*/
4458 createLabel (symbol * label, ast * stmnt)
4461 char name[SDCC_NAME_MAX + 1];
4464 /* must create fresh symbol if the symbol name */
4465 /* exists in the symbol table, since there can */
4466 /* be a variable with the same name as the labl */
4467 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4468 (csym->level == label->level))
4469 label = newSymbol (label->name, label->level);
4471 /* change the name before putting it in add _ */
4472 SNPRINTF(name, sizeof(name), "%s", label->name);
4474 /* put the label in the LabelSymbol table */
4475 /* but first check if a label of the same */
4477 if ((csym = findSym (LabelTab, NULL, name)))
4478 werror (E_DUPLICATE_LABEL, label->name);
4480 addSym (LabelTab, label, name, label->level, 0, 0);
4484 label->key = labelKey++;
4485 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4491 /*-----------------------------------------------------------------*/
4492 /* createCase - generates the parsetree for a case statement */
4493 /*-----------------------------------------------------------------*/
4495 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4497 char caseLbl[SDCC_NAME_MAX + 1];
4501 /* if the switch statement does not exist */
4502 /* then case is out of context */
4505 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4509 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4510 /* if not a constant then error */
4511 if (!IS_LITERAL (caseVal->ftype))
4513 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4517 /* if not a integer than error */
4518 if (!IS_INTEGRAL (caseVal->ftype))
4520 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4524 /* find the end of the switch values chain */
4525 if (!(val = swStat->values.switchVals.swVals))
4526 swStat->values.switchVals.swVals = caseVal->opval.val;
4529 /* also order the cases according to value */
4531 int cVal = (int) floatFromVal (caseVal->opval.val);
4532 while (val && (int) floatFromVal (val) < cVal)
4538 /* if we reached the end then */
4541 pval->next = caseVal->opval.val;
4543 else if ((int) floatFromVal (val) == cVal)
4545 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4551 /* we found a value greater than */
4552 /* the current value we must add this */
4553 /* before the value */
4554 caseVal->opval.val->next = val;
4556 /* if this was the first in chain */
4557 if (swStat->values.switchVals.swVals == val)
4558 swStat->values.switchVals.swVals =
4561 pval->next = caseVal->opval.val;
4566 /* create the case label */
4567 SNPRINTF(caseLbl, sizeof(caseLbl),
4569 swStat->values.switchVals.swNum,
4570 (int) floatFromVal (caseVal->opval.val));
4572 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4577 /*-----------------------------------------------------------------*/
4578 /* createDefault - creates the parse tree for the default statement */
4579 /*-----------------------------------------------------------------*/
4581 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4583 char defLbl[SDCC_NAME_MAX + 1];
4585 /* if the switch statement does not exist */
4586 /* then case is out of context */
4589 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4593 if (swStat->values.switchVals.swDefault)
4595 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4600 /* turn on the default flag */
4601 swStat->values.switchVals.swDefault = 1;
4603 /* create the label */
4604 SNPRINTF (defLbl, sizeof(defLbl),
4605 "_default_%d", swStat->values.switchVals.swNum);
4606 return createLabel (newSymbol (defLbl, 0), stmnt);
4609 /*-----------------------------------------------------------------*/
4610 /* createIf - creates the parsetree for the if statement */
4611 /*-----------------------------------------------------------------*/
4613 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4615 static int Lblnum = 0;
4617 symbol *ifTrue, *ifFalse, *ifEnd;
4619 /* if neither exists */
4620 if (!elseBody && !ifBody) {
4621 // if there are no side effects (i++, j() etc)
4622 if (!hasSEFcalls(condAst)) {
4627 /* create the labels */
4628 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4629 ifFalse = newSymbol (buffer, NestLevel);
4630 /* if no else body then end == false */
4635 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4636 ifEnd = newSymbol (buffer, NestLevel);
4639 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4640 ifTrue = newSymbol (buffer, NestLevel);
4644 /* attach the ifTrue label to the top of it body */
4645 ifBody = createLabel (ifTrue, ifBody);
4646 /* attach a goto end to the ifBody if else is present */
4649 ifBody = newNode (NULLOP, ifBody,
4651 newAst_VALUE (symbolVal (ifEnd)),
4653 /* put the elseLabel on the else body */
4654 elseBody = createLabel (ifFalse, elseBody);
4655 /* out the end at the end of the body */
4656 elseBody = newNode (NULLOP,
4658 createLabel (ifEnd, NULL));
4662 ifBody = newNode (NULLOP, ifBody,
4663 createLabel (ifFalse, NULL));
4665 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4666 if (IS_IFX (condAst))
4669 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4671 return newNode (NULLOP, ifTree,
4672 newNode (NULLOP, ifBody, elseBody));
4676 /*-----------------------------------------------------------------*/
4677 /* createDo - creates parse tree for do */
4680 /* _docontinue_n: */
4681 /* condition_expression +-> trueLabel -> _dobody_n */
4683 /* +-> falseLabel-> _dobreak_n */
4685 /*-----------------------------------------------------------------*/
4687 createDo (symbol * trueLabel, symbol * continueLabel,
4688 symbol * falseLabel, ast * condAst, ast * doBody)
4693 /* if the body does not exist then it is simple */
4696 condAst = backPatchLabels (condAst, continueLabel, NULL);
4697 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4698 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4699 doTree->trueLabel = continueLabel;
4700 doTree->falseLabel = NULL;
4704 /* otherwise we have a body */
4705 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4707 /* attach the body label to the top */
4708 doBody = createLabel (trueLabel, doBody);
4709 /* attach the continue label to end of body */
4710 doBody = newNode (NULLOP, doBody,
4711 createLabel (continueLabel, NULL));
4713 /* now put the break label at the end */
4714 if (IS_IFX (condAst))
4717 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4719 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4721 /* putting it together */
4722 return newNode (NULLOP, doBody, doTree);
4725 /*-----------------------------------------------------------------*/
4726 /* createFor - creates parse tree for 'for' statement */
4729 /* condExpr +-> trueLabel -> _forbody_n */
4731 /* +-> falseLabel-> _forbreak_n */
4734 /* _forcontinue_n: */
4736 /* goto _forcond_n ; */
4738 /*-----------------------------------------------------------------*/
4740 createFor (symbol * trueLabel, symbol * continueLabel,
4741 symbol * falseLabel, symbol * condLabel,
4742 ast * initExpr, ast * condExpr, ast * loopExpr,
4747 /* if loopexpression not present then we can generate it */
4748 /* the same way as a while */
4750 return newNode (NULLOP, initExpr,
4751 createWhile (trueLabel, continueLabel,
4752 falseLabel, condExpr, forBody));
4753 /* vanilla for statement */
4754 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4756 if (condExpr && !IS_IFX (condExpr))
4757 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4760 /* attach condition label to condition */
4761 condExpr = createLabel (condLabel, condExpr);
4763 /* attach body label to body */
4764 forBody = createLabel (trueLabel, forBody);
4766 /* attach continue to forLoop expression & attach */
4767 /* goto the forcond @ and of loopExpression */
4768 loopExpr = createLabel (continueLabel,
4772 newAst_VALUE (symbolVal (condLabel)),
4774 /* now start putting them together */
4775 forTree = newNode (NULLOP, initExpr, condExpr);
4776 forTree = newNode (NULLOP, forTree, forBody);
4777 forTree = newNode (NULLOP, forTree, loopExpr);
4778 /* finally add the break label */
4779 forTree = newNode (NULLOP, forTree,
4780 createLabel (falseLabel, NULL));
4784 /*-----------------------------------------------------------------*/
4785 /* createWhile - creates parse tree for while statement */
4786 /* the while statement will be created as follows */
4788 /* _while_continue_n: */
4789 /* condition_expression +-> trueLabel -> _while_boby_n */
4791 /* +-> falseLabel -> _while_break_n */
4792 /* _while_body_n: */
4794 /* goto _while_continue_n */
4795 /* _while_break_n: */
4796 /*-----------------------------------------------------------------*/
4798 createWhile (symbol * trueLabel, symbol * continueLabel,
4799 symbol * falseLabel, ast * condExpr, ast * whileBody)
4803 /* put the continue label */
4804 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4805 condExpr = createLabel (continueLabel, condExpr);
4806 condExpr->lineno = 0;
4808 /* put the body label in front of the body */
4809 whileBody = createLabel (trueLabel, whileBody);
4810 whileBody->lineno = 0;
4811 /* put a jump to continue at the end of the body */
4812 /* and put break label at the end of the body */
4813 whileBody = newNode (NULLOP,
4816 newAst_VALUE (symbolVal (continueLabel)),
4817 createLabel (falseLabel, NULL)));
4819 /* put it all together */
4820 if (IS_IFX (condExpr))
4821 whileTree = condExpr;
4824 whileTree = newNode (IFX, condExpr, NULL);
4825 /* put the true & false labels in place */
4826 whileTree->trueLabel = trueLabel;
4827 whileTree->falseLabel = falseLabel;
4830 return newNode (NULLOP, whileTree, whileBody);
4833 /*-----------------------------------------------------------------*/
4834 /* optimizeGetHbit - get highest order bit of the expression */
4835 /*-----------------------------------------------------------------*/
4837 optimizeGetHbit (ast * tree)
4840 /* if this is not a bit and */
4841 if (!IS_BITAND (tree))
4844 /* will look for tree of the form
4845 ( expr >> ((sizeof expr) -1) ) & 1 */
4846 if (!IS_AST_LIT_VALUE (tree->right))
4849 if (AST_LIT_VALUE (tree->right) != 1)
4852 if (!IS_RIGHT_OP (tree->left))
4855 if (!IS_AST_LIT_VALUE (tree->left->right))
4858 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4859 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4862 /* make sure the port supports GETHBIT */
4863 if (port->hasExtBitOp
4864 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4867 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4871 /*-----------------------------------------------------------------*/
4872 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4873 /*-----------------------------------------------------------------*/
4875 optimizeRRCRLC (ast * root)
4877 /* will look for trees of the form
4878 (?expr << 1) | (?expr >> 7) or
4879 (?expr >> 7) | (?expr << 1) will make that
4880 into a RLC : operation ..
4882 (?expr >> 1) | (?expr << 7) or
4883 (?expr << 7) | (?expr >> 1) will make that
4884 into a RRC operation
4885 note : by 7 I mean (number of bits required to hold the
4887 /* if the root operations is not a | operation the not */
4888 if (!IS_BITOR (root))
4891 /* I have to think of a better way to match patterns this sucks */
4892 /* that aside let start looking for the first case : I use a the
4893 negative check a lot to improve the efficiency */
4894 /* (?expr << 1) | (?expr >> 7) */
4895 if (IS_LEFT_OP (root->left) &&
4896 IS_RIGHT_OP (root->right))
4899 if (!SPEC_USIGN (TETYPE (root->left->left)))
4902 if (!IS_AST_LIT_VALUE (root->left->right) ||
4903 !IS_AST_LIT_VALUE (root->right->right))
4906 /* make sure it is the same expression */
4907 if (!isAstEqual (root->left->left,
4911 if (AST_LIT_VALUE (root->left->right) != 1)
4914 if (AST_LIT_VALUE (root->right->right) !=
4915 (getSize (TTYPE (root->left->left)) * 8 - 1))
4918 /* make sure the port supports RLC */
4919 if (port->hasExtBitOp
4920 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4923 /* whew got the first case : create the AST */
4924 return newNode (RLC, root->left->left, NULL);
4928 /* check for second case */
4929 /* (?expr >> 7) | (?expr << 1) */
4930 if (IS_LEFT_OP (root->right) &&
4931 IS_RIGHT_OP (root->left))
4934 if (!SPEC_USIGN (TETYPE (root->left->left)))
4937 if (!IS_AST_LIT_VALUE (root->left->right) ||
4938 !IS_AST_LIT_VALUE (root->right->right))
4941 /* make sure it is the same symbol */
4942 if (!isAstEqual (root->left->left,
4946 if (AST_LIT_VALUE (root->right->right) != 1)
4949 if (AST_LIT_VALUE (root->left->right) !=
4950 (getSize (TTYPE (root->left->left)) * 8 - 1))
4953 /* make sure the port supports RLC */
4954 if (port->hasExtBitOp
4955 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4958 /* whew got the first case : create the AST */
4959 return newNode (RLC, root->left->left, NULL);
4964 /* third case for RRC */
4965 /* (?symbol >> 1) | (?symbol << 7) */
4966 if (IS_LEFT_OP (root->right) &&
4967 IS_RIGHT_OP (root->left))
4970 if (!SPEC_USIGN (TETYPE (root->left->left)))
4973 if (!IS_AST_LIT_VALUE (root->left->right) ||
4974 !IS_AST_LIT_VALUE (root->right->right))
4977 /* make sure it is the same symbol */
4978 if (!isAstEqual (root->left->left,
4982 if (AST_LIT_VALUE (root->left->right) != 1)
4985 if (AST_LIT_VALUE (root->right->right) !=
4986 (getSize (TTYPE (root->left->left)) * 8 - 1))
4989 /* make sure the port supports RRC */
4990 if (port->hasExtBitOp
4991 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4994 /* whew got the first case : create the AST */
4995 return newNode (RRC, root->left->left, NULL);
4999 /* fourth and last case for now */
5000 /* (?symbol << 7) | (?symbol >> 1) */
5001 if (IS_RIGHT_OP (root->right) &&
5002 IS_LEFT_OP (root->left))
5005 if (!SPEC_USIGN (TETYPE (root->left->left)))
5008 if (!IS_AST_LIT_VALUE (root->left->right) ||
5009 !IS_AST_LIT_VALUE (root->right->right))
5012 /* make sure it is the same symbol */
5013 if (!isAstEqual (root->left->left,
5017 if (AST_LIT_VALUE (root->right->right) != 1)
5020 if (AST_LIT_VALUE (root->left->right) !=
5021 (getSize (TTYPE (root->left->left)) * 8 - 1))
5024 /* make sure the port supports RRC */
5025 if (port->hasExtBitOp
5026 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5029 /* whew got the first case : create the AST */
5030 return newNode (RRC, root->left->left, NULL);
5034 /* not found return root */
5038 /*-----------------------------------------------------------------*/
5039 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5040 /*-----------------------------------------------------------------*/
5042 optimizeSWAP (ast * root)
5044 /* will look for trees of the form
5045 (?expr << 4) | (?expr >> 4) or
5046 (?expr >> 4) | (?expr << 4) will make that
5047 into a SWAP : operation ..
5048 note : by 4 I mean (number of bits required to hold the
5050 /* if the root operations is not a | operation the not */
5051 if (!IS_BITOR (root))
5054 /* (?expr << 4) | (?expr >> 4) */
5055 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5056 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5059 if (!SPEC_USIGN (TETYPE (root->left->left)))
5062 if (!IS_AST_LIT_VALUE (root->left->right) ||
5063 !IS_AST_LIT_VALUE (root->right->right))
5066 /* make sure it is the same expression */
5067 if (!isAstEqual (root->left->left,
5071 if (AST_LIT_VALUE (root->left->right) !=
5072 (getSize (TTYPE (root->left->left)) * 4))
5075 if (AST_LIT_VALUE (root->right->right) !=
5076 (getSize (TTYPE (root->left->left)) * 4))
5079 /* make sure the port supports SWAP */
5080 if (port->hasExtBitOp
5081 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5084 /* found it : create the AST */
5085 return newNode (SWAP, root->left->left, NULL);
5089 /* not found return root */
5093 /*-----------------------------------------------------------------*/
5094 /* optimizeCompare - otimizes compares for bit variables */
5095 /*-----------------------------------------------------------------*/
5097 optimizeCompare (ast * root)
5099 ast *optExpr = NULL;
5102 unsigned int litValue;
5104 /* if nothing then return nothing */
5108 /* if not a compare op then do leaves */
5109 if (!IS_COMPARE_OP (root))
5111 root->left = optimizeCompare (root->left);
5112 root->right = optimizeCompare (root->right);
5116 /* if left & right are the same then depending
5117 of the operation do */
5118 if (isAstEqual (root->left, root->right))
5120 switch (root->opval.op)
5125 optExpr = newAst_VALUE (constVal ("0"));
5130 optExpr = newAst_VALUE (constVal ("1"));
5134 return decorateType (optExpr, RESULT_TYPE_NONE);
5137 vleft = (root->left->type == EX_VALUE ?
5138 root->left->opval.val : NULL);
5140 vright = (root->right->type == EX_VALUE ?
5141 root->right->opval.val : NULL);
5143 /* if left is a BITVAR in BITSPACE */
5144 /* and right is a LITERAL then opt- */
5145 /* imize else do nothing */
5146 if (vleft && vright &&
5147 IS_BITVAR (vleft->etype) &&
5148 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5149 IS_LITERAL (vright->etype))
5152 /* if right side > 1 then comparison may never succeed */
5153 if ((litValue = (int) floatFromVal (vright)) > 1)
5155 werror (W_BAD_COMPARE);
5161 switch (root->opval.op)
5163 case '>': /* bit value greater than 1 cannot be */
5164 werror (W_BAD_COMPARE);
5168 case '<': /* bit value < 1 means 0 */
5170 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5173 case LE_OP: /* bit value <= 1 means no check */
5174 optExpr = newAst_VALUE (vright);
5177 case GE_OP: /* bit value >= 1 means only check for = */
5179 optExpr = newAst_VALUE (vleft);
5184 { /* literal is zero */
5185 switch (root->opval.op)
5187 case '<': /* bit value < 0 cannot be */
5188 werror (W_BAD_COMPARE);
5192 case '>': /* bit value > 0 means 1 */
5194 optExpr = newAst_VALUE (vleft);
5197 case LE_OP: /* bit value <= 0 means no check */
5198 case GE_OP: /* bit value >= 0 means no check */
5199 werror (W_BAD_COMPARE);
5203 case EQ_OP: /* bit == 0 means ! of bit */
5204 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5208 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5209 } /* end-of-if of BITVAR */
5214 /*-----------------------------------------------------------------*/
5215 /* addSymToBlock : adds the symbol to the first block we find */
5216 /*-----------------------------------------------------------------*/
5218 addSymToBlock (symbol * sym, ast * tree)
5220 /* reached end of tree or a leaf */
5221 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5225 if (IS_AST_OP (tree) &&
5226 tree->opval.op == BLOCK)
5229 symbol *lsym = copySymbol (sym);
5231 lsym->next = AST_VALUES (tree, sym);
5232 AST_VALUES (tree, sym) = lsym;
5236 addSymToBlock (sym, tree->left);
5237 addSymToBlock (sym, tree->right);
5240 /*-----------------------------------------------------------------*/
5241 /* processRegParms - do processing for register parameters */
5242 /*-----------------------------------------------------------------*/
5244 processRegParms (value * args, ast * body)
5248 if (IS_REGPARM (args->etype))
5249 addSymToBlock (args->sym, body);
5254 /*-----------------------------------------------------------------*/
5255 /* resetParmKey - resets the operandkeys for the symbols */
5256 /*-----------------------------------------------------------------*/
5257 DEFSETFUNC (resetParmKey)
5268 /*-----------------------------------------------------------------*/
5269 /* createFunction - This is the key node that calls the iCode for */
5270 /* generating the code for a function. Note code */
5271 /* is generated function by function, later when */
5272 /* add inter-procedural analysis this will change */
5273 /*-----------------------------------------------------------------*/
5275 createFunction (symbol * name, ast * body)
5281 iCode *piCode = NULL;
5283 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5284 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5286 /* if check function return 0 then some problem */
5287 if (checkFunction (name, NULL) == 0)
5290 /* create a dummy block if none exists */
5292 body = newNode (BLOCK, NULL, NULL);
5296 /* check if the function name already in the symbol table */
5297 if ((csym = findSym (SymbolTab, NULL, name->name)))
5300 /* special case for compiler defined functions
5301 we need to add the name to the publics list : this
5302 actually means we are now compiling the compiler
5306 addSet (&publics, name);
5312 allocVariables (name);
5314 name->lastLine = mylineno;
5317 /* set the stack pointer */
5318 stackPtr = -port->stack.direction * port->stack.call_overhead;
5319 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5321 if (IFFUNC_ISISR (name->type))
5322 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5324 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5326 if (options.useXstack)
5327 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5329 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5332 fetype = getSpec (name->type); /* get the specifier for the function */
5333 /* if this is a reentrant function then */
5334 if (IFFUNC_ISREENT (name->type))
5337 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5339 /* do processing for parameters that are passed in registers */
5340 processRegParms (FUNC_ARGS(name->type), body);
5342 /* set the stack pointer */
5346 /* allocate & autoinit the block variables */
5347 processBlockVars (body, &stack, ALLOCATE);
5349 /* save the stack information */
5350 if (options.useXstack)
5351 name->xstack = SPEC_STAK (fetype) = stack;
5353 name->stack = SPEC_STAK (fetype) = stack;
5355 /* name needs to be mangled */
5356 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5358 body = resolveSymbols (body); /* resolve the symbols */
5359 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5362 ex = newAst_VALUE (symbolVal (name)); /* create name */
5363 ex = newNode (FUNCTION, ex, body);
5364 ex->values.args = FUNC_ARGS(name->type);
5366 if (options.dump_tree) PA(ex);
5369 werror (E_FUNC_NO_CODE, name->name);
5373 /* create the node & generate intermediate code */
5375 codeOutFile = code->oFile;
5376 piCode = iCodeFromAst (ex);
5380 werror (E_FUNC_NO_CODE, name->name);
5384 eBBlockFromiCode (piCode);
5386 /* if there are any statics then do them */
5389 GcurMemmap = statsg;
5390 codeOutFile = statsg->oFile;
5391 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5397 /* dealloc the block variables */
5398 processBlockVars (body, &stack, DEALLOCATE);
5399 outputDebugStackSymbols();
5400 /* deallocate paramaters */
5401 deallocParms (FUNC_ARGS(name->type));
5403 if (IFFUNC_ISREENT (name->type))
5406 /* we are done freeup memory & cleanup */
5408 if (port->reset_labelKey) labelKey = 1;
5410 FUNC_HASBODY(name->type) = 1;
5411 addSet (&operKeyReset, name);
5412 applyToSet (operKeyReset, resetParmKey);
5417 cleanUpLevel (LabelTab, 0);
5418 cleanUpBlock (StructTab, 1);
5419 cleanUpBlock (TypedefTab, 1);
5421 xstack->syms = NULL;
5422 istack->syms = NULL;
5427 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5428 /*-----------------------------------------------------------------*/
5429 /* ast_print : prints the ast (for debugging purposes) */
5430 /*-----------------------------------------------------------------*/
5432 void ast_print (ast * tree, FILE *outfile, int indent)
5437 /* can print only decorated trees */
5438 if (!tree->decorated) return;
5440 /* if any child is an error | this one is an error do nothing */
5441 if (tree->isError ||
5442 (tree->left && tree->left->isError) ||
5443 (tree->right && tree->right->isError)) {
5444 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5448 /* print the line */
5449 /* if not block & function */
5450 if (tree->type == EX_OP &&
5451 (tree->opval.op != FUNCTION &&
5452 tree->opval.op != BLOCK &&
5453 tree->opval.op != NULLOP)) {
5456 if (tree->opval.op == FUNCTION) {
5458 value *args=FUNC_ARGS(tree->left->opval.val->type);
5459 fprintf(outfile,"FUNCTION (%s=%p) type (",
5460 tree->left->opval.val->name, tree);
5461 printTypeChain (tree->left->opval.val->type->next,outfile);
5462 fprintf(outfile,") args (");
5465 fprintf (outfile, ", ");
5467 printTypeChain (args ? args->type : NULL, outfile);
5469 args= args ? args->next : NULL;
5471 fprintf(outfile,")\n");
5472 ast_print(tree->left,outfile,indent);
5473 ast_print(tree->right,outfile,indent);
5476 if (tree->opval.op == BLOCK) {
5477 symbol *decls = tree->values.sym;
5478 INDENT(indent,outfile);
5479 fprintf(outfile,"{\n");
5481 INDENT(indent+2,outfile);
5482 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5483 decls->name, decls);
5484 printTypeChain(decls->type,outfile);
5485 fprintf(outfile,")\n");
5487 decls = decls->next;
5489 ast_print(tree->right,outfile,indent+2);
5490 INDENT(indent,outfile);
5491 fprintf(outfile,"}\n");
5494 if (tree->opval.op == NULLOP) {
5495 ast_print(tree->left,outfile,indent);
5496 ast_print(tree->right,outfile,indent);
5499 INDENT(indent,outfile);
5501 /*------------------------------------------------------------------*/
5502 /*----------------------------*/
5503 /* leaf has been reached */
5504 /*----------------------------*/
5505 /* if this is of type value */
5506 /* just get the type */
5507 if (tree->type == EX_VALUE) {
5509 if (IS_LITERAL (tree->opval.val->etype)) {
5510 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5511 if (SPEC_USIGN (tree->opval.val->etype))
5512 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5514 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5515 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5516 floatFromVal(tree->opval.val));
5517 } else if (tree->opval.val->sym) {
5518 /* if the undefined flag is set then give error message */
5519 if (tree->opval.val->sym->undefined) {
5520 fprintf(outfile,"UNDEFINED SYMBOL ");
5522 fprintf(outfile,"SYMBOL ");
5524 fprintf(outfile,"(%s=%p)",
5525 tree->opval.val->sym->name,tree);
5528 fprintf(outfile," type (");
5529 printTypeChain(tree->ftype,outfile);
5530 fprintf(outfile,")\n");
5532 fprintf(outfile,"\n");
5537 /* if type link for the case of cast */
5538 if (tree->type == EX_LINK) {
5539 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5540 printTypeChain(tree->opval.lnk,outfile);
5541 fprintf(outfile,")\n");
5546 /* depending on type of operator do */
5548 switch (tree->opval.op) {
5549 /*------------------------------------------------------------------*/
5550 /*----------------------------*/
5552 /*----------------------------*/
5554 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5555 printTypeChain(tree->ftype,outfile);
5556 fprintf(outfile,")\n");
5557 ast_print(tree->left,outfile,indent+2);
5558 ast_print(tree->right,outfile,indent+2);
5561 /*------------------------------------------------------------------*/
5562 /*----------------------------*/
5564 /*----------------------------*/
5566 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5567 printTypeChain(tree->ftype,outfile);
5568 fprintf(outfile,")\n");
5569 ast_print(tree->left,outfile,indent+2);
5570 ast_print(tree->right,outfile,indent+2);
5573 /*------------------------------------------------------------------*/
5574 /*----------------------------*/
5575 /* struct/union pointer */
5576 /*----------------------------*/
5578 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5579 printTypeChain(tree->ftype,outfile);
5580 fprintf(outfile,")\n");
5581 ast_print(tree->left,outfile,indent+2);
5582 ast_print(tree->right,outfile,indent+2);
5585 /*------------------------------------------------------------------*/
5586 /*----------------------------*/
5587 /* ++/-- operation */
5588 /*----------------------------*/
5591 fprintf(outfile,"post-");
5593 fprintf(outfile,"pre-");
5594 fprintf(outfile,"INC_OP (%p) type (",tree);
5595 printTypeChain(tree->ftype,outfile);
5596 fprintf(outfile,")\n");
5597 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5598 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5603 fprintf(outfile,"post-");
5605 fprintf(outfile,"pre-");
5606 fprintf(outfile,"DEC_OP (%p) type (",tree);
5607 printTypeChain(tree->ftype,outfile);
5608 fprintf(outfile,")\n");
5609 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5610 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5613 /*------------------------------------------------------------------*/
5614 /*----------------------------*/
5616 /*----------------------------*/
5619 fprintf(outfile,"& (%p) type (",tree);
5620 printTypeChain(tree->ftype,outfile);
5621 fprintf(outfile,")\n");
5622 ast_print(tree->left,outfile,indent+2);
5623 ast_print(tree->right,outfile,indent+2);
5625 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5626 printTypeChain(tree->ftype,outfile);
5627 fprintf(outfile,")\n");
5628 ast_print(tree->left,outfile,indent+2);
5629 ast_print(tree->right,outfile,indent+2);
5632 /*----------------------------*/
5634 /*----------------------------*/
5636 fprintf(outfile,"OR (%p) type (",tree);
5637 printTypeChain(tree->ftype,outfile);
5638 fprintf(outfile,")\n");
5639 ast_print(tree->left,outfile,indent+2);
5640 ast_print(tree->right,outfile,indent+2);
5642 /*------------------------------------------------------------------*/
5643 /*----------------------------*/
5645 /*----------------------------*/
5647 fprintf(outfile,"XOR (%p) type (",tree);
5648 printTypeChain(tree->ftype,outfile);
5649 fprintf(outfile,")\n");
5650 ast_print(tree->left,outfile,indent+2);
5651 ast_print(tree->right,outfile,indent+2);
5654 /*------------------------------------------------------------------*/
5655 /*----------------------------*/
5657 /*----------------------------*/
5659 fprintf(outfile,"DIV (%p) type (",tree);
5660 printTypeChain(tree->ftype,outfile);
5661 fprintf(outfile,")\n");
5662 ast_print(tree->left,outfile,indent+2);
5663 ast_print(tree->right,outfile,indent+2);
5665 /*------------------------------------------------------------------*/
5666 /*----------------------------*/
5668 /*----------------------------*/
5670 fprintf(outfile,"MOD (%p) type (",tree);
5671 printTypeChain(tree->ftype,outfile);
5672 fprintf(outfile,")\n");
5673 ast_print(tree->left,outfile,indent+2);
5674 ast_print(tree->right,outfile,indent+2);
5677 /*------------------------------------------------------------------*/
5678 /*----------------------------*/
5679 /* address dereference */
5680 /*----------------------------*/
5681 case '*': /* can be unary : if right is null then unary operation */
5683 fprintf(outfile,"DEREF (%p) type (",tree);
5684 printTypeChain(tree->ftype,outfile);
5685 fprintf(outfile,")\n");
5686 ast_print(tree->left,outfile,indent+2);
5689 /*------------------------------------------------------------------*/
5690 /*----------------------------*/
5691 /* multiplication */
5692 /*----------------------------*/
5693 fprintf(outfile,"MULT (%p) type (",tree);
5694 printTypeChain(tree->ftype,outfile);
5695 fprintf(outfile,")\n");
5696 ast_print(tree->left,outfile,indent+2);
5697 ast_print(tree->right,outfile,indent+2);
5701 /*------------------------------------------------------------------*/
5702 /*----------------------------*/
5703 /* unary '+' operator */
5704 /*----------------------------*/
5708 fprintf(outfile,"UPLUS (%p) type (",tree);
5709 printTypeChain(tree->ftype,outfile);
5710 fprintf(outfile,")\n");
5711 ast_print(tree->left,outfile,indent+2);
5713 /*------------------------------------------------------------------*/
5714 /*----------------------------*/
5716 /*----------------------------*/
5717 fprintf(outfile,"ADD (%p) type (",tree);
5718 printTypeChain(tree->ftype,outfile);
5719 fprintf(outfile,")\n");
5720 ast_print(tree->left,outfile,indent+2);
5721 ast_print(tree->right,outfile,indent+2);
5724 /*------------------------------------------------------------------*/
5725 /*----------------------------*/
5727 /*----------------------------*/
5728 case '-': /* can be unary */
5730 fprintf(outfile,"UMINUS (%p) type (",tree);
5731 printTypeChain(tree->ftype,outfile);
5732 fprintf(outfile,")\n");
5733 ast_print(tree->left,outfile,indent+2);
5735 /*------------------------------------------------------------------*/
5736 /*----------------------------*/
5738 /*----------------------------*/
5739 fprintf(outfile,"SUB (%p) type (",tree);
5740 printTypeChain(tree->ftype,outfile);
5741 fprintf(outfile,")\n");
5742 ast_print(tree->left,outfile,indent+2);
5743 ast_print(tree->right,outfile,indent+2);
5746 /*------------------------------------------------------------------*/
5747 /*----------------------------*/
5749 /*----------------------------*/
5751 fprintf(outfile,"COMPL (%p) type (",tree);
5752 printTypeChain(tree->ftype,outfile);
5753 fprintf(outfile,")\n");
5754 ast_print(tree->left,outfile,indent+2);
5756 /*------------------------------------------------------------------*/
5757 /*----------------------------*/
5759 /*----------------------------*/
5761 fprintf(outfile,"NOT (%p) type (",tree);
5762 printTypeChain(tree->ftype,outfile);
5763 fprintf(outfile,")\n");
5764 ast_print(tree->left,outfile,indent+2);
5766 /*------------------------------------------------------------------*/
5767 /*----------------------------*/
5769 /*----------------------------*/
5771 fprintf(outfile,"RRC (%p) type (",tree);
5772 printTypeChain(tree->ftype,outfile);
5773 fprintf(outfile,")\n");
5774 ast_print(tree->left,outfile,indent+2);
5778 fprintf(outfile,"RLC (%p) type (",tree);
5779 printTypeChain(tree->ftype,outfile);
5780 fprintf(outfile,")\n");
5781 ast_print(tree->left,outfile,indent+2);
5784 fprintf(outfile,"SWAP (%p) type (",tree);
5785 printTypeChain(tree->ftype,outfile);
5786 fprintf(outfile,")\n");
5787 ast_print(tree->left,outfile,indent+2);
5790 fprintf(outfile,"GETHBIT (%p) type (",tree);
5791 printTypeChain(tree->ftype,outfile);
5792 fprintf(outfile,")\n");
5793 ast_print(tree->left,outfile,indent+2);
5796 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5797 printTypeChain(tree->ftype,outfile);
5798 fprintf(outfile,")\n");
5799 ast_print(tree->left,outfile,indent+2);
5800 ast_print(tree->right,outfile,indent+2);
5803 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5804 printTypeChain(tree->ftype,outfile);
5805 fprintf(outfile,")\n");
5806 ast_print(tree->left,outfile,indent+2);
5807 ast_print(tree->right,outfile,indent+2);
5809 /*------------------------------------------------------------------*/
5810 /*----------------------------*/
5812 /*----------------------------*/
5813 case CAST: /* change the type */
5814 fprintf(outfile,"CAST (%p) from type (",tree);
5815 printTypeChain(tree->right->ftype,outfile);
5816 fprintf(outfile,") to type (");
5817 printTypeChain(tree->ftype,outfile);
5818 fprintf(outfile,")\n");
5819 ast_print(tree->right,outfile,indent+2);
5823 fprintf(outfile,"ANDAND (%p) type (",tree);
5824 printTypeChain(tree->ftype,outfile);
5825 fprintf(outfile,")\n");
5826 ast_print(tree->left,outfile,indent+2);
5827 ast_print(tree->right,outfile,indent+2);
5830 fprintf(outfile,"OROR (%p) type (",tree);
5831 printTypeChain(tree->ftype,outfile);
5832 fprintf(outfile,")\n");
5833 ast_print(tree->left,outfile,indent+2);
5834 ast_print(tree->right,outfile,indent+2);
5837 /*------------------------------------------------------------------*/
5838 /*----------------------------*/
5839 /* comparison operators */
5840 /*----------------------------*/
5842 fprintf(outfile,"GT(>) (%p) type (",tree);
5843 printTypeChain(tree->ftype,outfile);
5844 fprintf(outfile,")\n");
5845 ast_print(tree->left,outfile,indent+2);
5846 ast_print(tree->right,outfile,indent+2);
5849 fprintf(outfile,"LT(<) (%p) type (",tree);
5850 printTypeChain(tree->ftype,outfile);
5851 fprintf(outfile,")\n");
5852 ast_print(tree->left,outfile,indent+2);
5853 ast_print(tree->right,outfile,indent+2);
5856 fprintf(outfile,"LE(<=) (%p) type (",tree);
5857 printTypeChain(tree->ftype,outfile);
5858 fprintf(outfile,")\n");
5859 ast_print(tree->left,outfile,indent+2);
5860 ast_print(tree->right,outfile,indent+2);
5863 fprintf(outfile,"GE(>=) (%p) type (",tree);
5864 printTypeChain(tree->ftype,outfile);
5865 fprintf(outfile,")\n");
5866 ast_print(tree->left,outfile,indent+2);
5867 ast_print(tree->right,outfile,indent+2);
5870 fprintf(outfile,"EQ(==) (%p) type (",tree);
5871 printTypeChain(tree->ftype,outfile);
5872 fprintf(outfile,")\n");
5873 ast_print(tree->left,outfile,indent+2);
5874 ast_print(tree->right,outfile,indent+2);
5877 fprintf(outfile,"NE(!=) (%p) type (",tree);
5878 printTypeChain(tree->ftype,outfile);
5879 fprintf(outfile,")\n");
5880 ast_print(tree->left,outfile,indent+2);
5881 ast_print(tree->right,outfile,indent+2);
5882 /*------------------------------------------------------------------*/
5883 /*----------------------------*/
5885 /*----------------------------*/
5886 case SIZEOF: /* evaluate wihout code generation */
5887 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5890 /*------------------------------------------------------------------*/
5891 /*----------------------------*/
5892 /* conditional operator '?' */
5893 /*----------------------------*/
5895 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5896 printTypeChain(tree->ftype,outfile);
5897 fprintf(outfile,")\n");
5898 ast_print(tree->left,outfile,indent+2);
5899 ast_print(tree->right,outfile,indent+2);
5903 fprintf(outfile,"COLON(:) (%p) type (",tree);
5904 printTypeChain(tree->ftype,outfile);
5905 fprintf(outfile,")\n");
5906 ast_print(tree->left,outfile,indent+2);
5907 ast_print(tree->right,outfile,indent+2);
5910 /*------------------------------------------------------------------*/
5911 /*----------------------------*/
5912 /* assignment operators */
5913 /*----------------------------*/
5915 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5916 printTypeChain(tree->ftype,outfile);
5917 fprintf(outfile,")\n");
5918 ast_print(tree->left,outfile,indent+2);
5919 ast_print(tree->right,outfile,indent+2);
5922 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5923 printTypeChain(tree->ftype,outfile);
5924 fprintf(outfile,")\n");
5925 ast_print(tree->left,outfile,indent+2);
5926 ast_print(tree->right,outfile,indent+2);
5929 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5930 printTypeChain(tree->ftype,outfile);
5931 fprintf(outfile,")\n");
5932 ast_print(tree->left,outfile,indent+2);
5933 ast_print(tree->right,outfile,indent+2);
5936 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5937 printTypeChain(tree->ftype,outfile);
5938 fprintf(outfile,")\n");
5939 ast_print(tree->left,outfile,indent+2);
5940 ast_print(tree->right,outfile,indent+2);
5943 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5944 printTypeChain(tree->ftype,outfile);
5945 fprintf(outfile,")\n");
5946 ast_print(tree->left,outfile,indent+2);
5947 ast_print(tree->right,outfile,indent+2);
5950 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5951 printTypeChain(tree->ftype,outfile);
5952 fprintf(outfile,")\n");
5953 ast_print(tree->left,outfile,indent+2);
5954 ast_print(tree->right,outfile,indent+2);
5957 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5958 printTypeChain(tree->ftype,outfile);
5959 fprintf(outfile,")\n");
5960 ast_print(tree->left,outfile,indent+2);
5961 ast_print(tree->right,outfile,indent+2);
5963 /*------------------------------------------------------------------*/
5964 /*----------------------------*/
5966 /*----------------------------*/
5968 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5969 printTypeChain(tree->ftype,outfile);
5970 fprintf(outfile,")\n");
5971 ast_print(tree->left,outfile,indent+2);
5972 ast_print(tree->right,outfile,indent+2);
5974 /*------------------------------------------------------------------*/
5975 /*----------------------------*/
5977 /*----------------------------*/
5979 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5980 printTypeChain(tree->ftype,outfile);
5981 fprintf(outfile,")\n");
5982 ast_print(tree->left,outfile,indent+2);
5983 ast_print(tree->right,outfile,indent+2);
5985 /*------------------------------------------------------------------*/
5986 /*----------------------------*/
5987 /* straight assignemnt */
5988 /*----------------------------*/
5990 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5991 printTypeChain(tree->ftype,outfile);
5992 fprintf(outfile,")\n");
5993 ast_print(tree->left,outfile,indent+2);
5994 ast_print(tree->right,outfile,indent+2);
5996 /*------------------------------------------------------------------*/
5997 /*----------------------------*/
5998 /* comma operator */
5999 /*----------------------------*/
6001 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6002 printTypeChain(tree->ftype,outfile);
6003 fprintf(outfile,")\n");
6004 ast_print(tree->left,outfile,indent+2);
6005 ast_print(tree->right,outfile,indent+2);
6007 /*------------------------------------------------------------------*/
6008 /*----------------------------*/
6010 /*----------------------------*/
6013 fprintf(outfile,"CALL (%p) type (",tree);
6014 printTypeChain(tree->ftype,outfile);
6015 fprintf(outfile,")\n");
6016 ast_print(tree->left,outfile,indent+2);
6017 ast_print(tree->right,outfile,indent+2);
6020 fprintf(outfile,"PARMS\n");
6021 ast_print(tree->left,outfile,indent+2);
6022 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6023 ast_print(tree->right,outfile,indent+2);
6026 /*------------------------------------------------------------------*/
6027 /*----------------------------*/
6028 /* return statement */
6029 /*----------------------------*/
6031 fprintf(outfile,"RETURN (%p) type (",tree);
6033 printTypeChain(tree->right->ftype,outfile);
6035 fprintf(outfile,")\n");
6036 ast_print(tree->right,outfile,indent+2);
6038 /*------------------------------------------------------------------*/
6039 /*----------------------------*/
6040 /* label statement */
6041 /*----------------------------*/
6043 fprintf(outfile,"LABEL (%p)\n",tree);
6044 ast_print(tree->left,outfile,indent+2);
6045 ast_print(tree->right,outfile,indent);
6047 /*------------------------------------------------------------------*/
6048 /*----------------------------*/
6049 /* switch statement */
6050 /*----------------------------*/
6054 fprintf(outfile,"SWITCH (%p) ",tree);
6055 ast_print(tree->left,outfile,0);
6056 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6057 INDENT(indent+2,outfile);
6058 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6059 (int) floatFromVal(val),
6060 tree->values.switchVals.swNum,
6061 (int) floatFromVal(val));
6063 ast_print(tree->right,outfile,indent);
6066 /*------------------------------------------------------------------*/
6067 /*----------------------------*/
6069 /*----------------------------*/
6071 fprintf(outfile,"IF (%p) \n",tree);
6072 ast_print(tree->left,outfile,indent+2);
6073 if (tree->trueLabel) {
6074 INDENT(indent+2,outfile);
6075 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6077 if (tree->falseLabel) {
6078 INDENT(indent+2,outfile);
6079 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6081 ast_print(tree->right,outfile,indent+2);
6083 /*----------------------------*/
6084 /* goto Statement */
6085 /*----------------------------*/
6087 fprintf(outfile,"GOTO (%p) \n",tree);
6088 ast_print(tree->left,outfile,indent+2);
6089 fprintf(outfile,"\n");
6091 /*------------------------------------------------------------------*/
6092 /*----------------------------*/
6094 /*----------------------------*/
6096 fprintf(outfile,"FOR (%p) \n",tree);
6097 if (AST_FOR( tree, initExpr)) {
6098 INDENT(indent+2,outfile);
6099 fprintf(outfile,"INIT EXPR ");
6100 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6102 if (AST_FOR( tree, condExpr)) {
6103 INDENT(indent+2,outfile);
6104 fprintf(outfile,"COND EXPR ");
6105 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6107 if (AST_FOR( tree, loopExpr)) {
6108 INDENT(indent+2,outfile);
6109 fprintf(outfile,"LOOP EXPR ");
6110 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6112 fprintf(outfile,"FOR LOOP BODY \n");
6113 ast_print(tree->left,outfile,indent+2);
6116 fprintf(outfile,"CRITICAL (%p) \n",tree);
6117 ast_print(tree->left,outfile,indent+2);
6125 ast_print(t,stdout,0);
6130 /*-----------------------------------------------------------------*/
6131 /* astErrors : returns non-zero if errors present in tree */
6132 /*-----------------------------------------------------------------*/
6133 int astErrors(ast *t)
6142 if (t->type == EX_VALUE
6143 && t->opval.val->sym
6144 && t->opval.val->sym->undefined)
6147 errors += astErrors(t->left);
6148 errors += astErrors(t->right);