X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=f57bc1489db9bd8de82c98f483d28b920f2a1b94;hb=90bdb43b342189fcb94a398855d43f3f47f96738;hp=a3fb39df8e7048a02e769ec735c62fcdc83885d9;hpb=48ba82a9755eae5da6e24d1381ea3bcf72ebb9ef;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index a3fb39df..f57bc148 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -50,18 +50,21 @@ int labelKey = 1; int noLineno = 0; int noAlloc = 0; symbol *currFunc=NULL; -static ast *createIval (ast *, sym_link *, initList *, ast *); -static ast *createIvalCharPtr (ast *, sym_link *, ast *); +static ast *createIval (ast *, sym_link *, initList *, ast *, ast *); +static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *); static ast *optimizeCompare (ast *); ast *optimizeRRCRLC (ast *); ast *optimizeSWAP (ast *); -ast *optimizeGetHbit (ast *); -ast *backPatchLabels (ast *, symbol *, symbol *); +ast *optimizeGetHbit (ast *, RESULT_TYPE); +ast *optimizeGetAbit (ast *, RESULT_TYPE); +ast *optimizeGetByte (ast *, RESULT_TYPE); +ast *optimizeGetWord (ast *, RESULT_TYPE); +static ast *backPatchLabels (ast *, symbol *, symbol *); void PA(ast *t); int inInitMode = 0; memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */ FILE *codeOutFile; -int +int ptt (ast * tree) { printTypeChain (tree->ftype, stdout); @@ -142,13 +145,13 @@ newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel) { /* then depending on the expression value */ if (floatFromVal (condAst->opval.val)) - ifxNode = newNode (GOTO, - newAst_VALUE (symbolVal (trueLabel)), - NULL); + ifxNode = newNode (GOTO, + newAst_VALUE (symbolVal (trueLabel)), + NULL); else - ifxNode = newNode (GOTO, - newAst_VALUE (symbolVal (falseLabel)), - NULL); + ifxNode = newNode (GOTO, + newAst_VALUE (symbolVal (falseLabel)), + NULL); } else { @@ -174,11 +177,11 @@ copyAstValues (ast * dest, ast * src) case SWITCH: dest->values.switchVals.swVals = - copyValue (src->values.switchVals.swVals); + copyValue (src->values.switchVals.swVals); dest->values.switchVals.swDefault = - src->values.switchVals.swDefault; + src->values.switchVals.swDefault; dest->values.switchVals.swNum = - src->values.switchVals.swNum; + src->values.switchVals.swNum; break; case INLINEASM: @@ -186,8 +189,8 @@ copyAstValues (ast * dest, ast * src) break; case ARRAYINIT: - dest->values.constlist = copyLiteralList(src->values.constlist); - break; + dest->values.constlist = copyLiteralList(src->values.constlist); + break; case FOR: AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel)); @@ -218,6 +221,7 @@ copyAst (ast * src) dest->lineno = src->lineno; dest->level = src->level; dest->funcName = src->funcName; + dest->reversed = src->reversed; if (src->ftype) dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype)); @@ -250,7 +254,7 @@ exit: return dest; } - +#if 0 /*-----------------------------------------------------------------*/ /* removeIncDecOps: remove for side effects in *_ASSIGN's */ /* "*s++ += 3" -> "*s++ = *s++ + 3" */ @@ -321,9 +325,91 @@ ast *removePostIncDecOps (ast * tree) { return tree; } +#endif +/*-----------------------------------------------------------------*/ +/* replaceAstWithTemporary: Replace the AST pointed to by the arg */ +/* with a reference to a new temporary variable. Returns*/ +/* an AST which assigns the original value to the */ +/* temporary. */ +/*-----------------------------------------------------------------*/ +static ast *replaceAstWithTemporary(ast **treeptr) +{ + symbol *sym = newSymbol (genSymName(NestLevel), NestLevel ); + ast *tempvar; + + /* Tell gatherImplicitVariables() to automatically give the + symbol the correct type */ + sym->infertype = 1; + sym->type = NULL; + sym->etype = NULL; + + tempvar = newNode('=', newAst_VALUE(symbolVal(sym)), *treeptr); + *treeptr = newAst_VALUE(symbolVal(sym)); + + addSymChain(&sym); + + return tempvar; +} + +/*-----------------------------------------------------------------*/ +/* createRMW: Create a read-modify-write expression, using a */ +/* temporary variable if necessary to avoid duplicating */ +/* any side effects, for use in e.g. */ +/* foo()->count += 5; becomes */ +/* tmp = foo(); tmp->count = tmp->count + 5; */ +/*-----------------------------------------------------------------*/ +ast * createRMW (ast *target, unsigned op, ast *operand) +{ + ast *readval, *writeval; + ast *tempvar1 = NULL; + ast *tempvar2 = NULL; + ast *result; + + if (!target || !operand) { + return NULL; + } + + /* we need to create two copies of target: one to read from and + one to write to. but we need to do this without duplicating + any side effects that may be contained in the tree. */ + + if (IS_AST_OP(target)) { + /* if this is a dereference, put the referenced item in the temporary */ + if (IS_DEREF_OP(target) || target->opval.op == PTR_OP) { + /* create a new temporary containing the item being dereferenced */ + if (hasSEFcalls(target->left)) + tempvar1 = replaceAstWithTemporary(&(target->left)); + } else if (target->opval.op == '[') { + /* Array access is similar, but we have to avoid side effects in + both values [WIML: Why not transform a[b] to *(a+b) in parser?] */ + if (hasSEFcalls(target->left)) + tempvar1 = replaceAstWithTemporary(&(target->left)); + if (hasSEFcalls(target->right)) + tempvar2 = replaceAstWithTemporary(&(target->right)); + } else { + /* we would have to handle '.', but it is not generated any more */ + wassertl(target->opval.op != '.', "obsolete opcode in tree"); + + /* no other kinds of ASTs are lvalues and can contain side effects */ + } + } + + readval = target; + writeval = copyAst(target); + + result = newNode('=', writeval, newNode(op, readval, operand)); + if (tempvar2) + result = newNode(',', tempvar2, result); + if (tempvar1) + result = newNode(',', tempvar1, result); + + return result; + +} /*-----------------------------------------------------------------*/ -/* hasSEFcalls - returns TRUE if tree has a function call */ +/* hasSEFcalls - returns TRUE if tree has a function call, */ +/* inc/decrement, or other side effect */ /*-----------------------------------------------------------------*/ bool hasSEFcalls (ast * tree) @@ -340,7 +426,7 @@ hasSEFcalls (ast * tree) return TRUE; return (hasSEFcalls (tree->left) | - hasSEFcalls (tree->right)); + hasSEFcalls (tree->right)); } /*-----------------------------------------------------------------*/ @@ -363,28 +449,28 @@ isAstEqual (ast * t1, ast * t2) { case EX_OP: if (t1->opval.op != t2->opval.op) - return 0; + return 0; return (isAstEqual (t1->left, t2->left) && - isAstEqual (t1->right, t2->right)); + isAstEqual (t1->right, t2->right)); break; case EX_VALUE: if (t1->opval.val->sym) - { - if (!t2->opval.val->sym) - return 0; - else - return isSymbolEqual (t1->opval.val->sym, - t2->opval.val->sym); - } + { + if (!t2->opval.val->sym) + return 0; + else + return isSymbolEqual (t1->opval.val->sym, + t2->opval.val->sym); + } else - { - if (t2->opval.val->sym) - return 0; - else - return (floatFromVal (t1->opval.val) == - floatFromVal (t2->opval.val)); - } + { + if (t2->opval.val->sym) + return 0; + else + return (floatFromVal (t1->opval.val) == + floatFromVal (t2->opval.val)); + } break; /* only compare these two types */ @@ -427,25 +513,25 @@ resolveSymbols (ast * tree) symbol *csym; if (tree->trueLabel) - { - if ((csym = findSym (LabelTab, tree->trueLabel, - tree->trueLabel->name))) - tree->trueLabel = csym; - else - werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, - tree->trueLabel->name); - } + { + if ((csym = findSym (LabelTab, tree->trueLabel, + tree->trueLabel->name))) + tree->trueLabel = csym; + else + werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, + tree->trueLabel->name); + } if (tree->falseLabel) - { - if ((csym = findSym (LabelTab, - tree->falseLabel, - tree->falseLabel->name))) - tree->falseLabel = csym; - else - werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, - tree->falseLabel->name); - } + { + if ((csym = findSym (LabelTab, + tree->falseLabel, + tree->falseLabel->name))) + tree->falseLabel = csym; + else + werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, + tree->falseLabel->name); + } } @@ -456,13 +542,13 @@ resolveSymbols (ast * tree) { symbol *csym = findSym (LabelTab, tree->opval.val->sym, - tree->opval.val->sym->name); + tree->opval.val->sym->name); if (!csym) - werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, - tree->opval.val->sym->name); + werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, + tree->opval.val->sym->name); else - tree->opval.val->sym = csym; + tree->opval.val->sym = csym; goto resolveChildren; } @@ -477,42 +563,42 @@ resolveSymbols (ast * tree) /* if found in the symbol table & they r not the same */ if (csym && tree->opval.val->sym != csym) - { - tree->opval.val->sym = csym; - tree->opval.val->type = csym->type; - tree->opval.val->etype = csym->etype; - } + { + tree->opval.val->sym = csym; + tree->opval.val->type = csym->type; + tree->opval.val->etype = csym->etype; + } /* if not found in the symbol table */ /* mark it as undefined assume it is */ /* an integer in data space */ if (!csym && !tree->opval.val->sym->implicit) - { - - /* if this is a function name then */ - /* mark it as returning an int */ - if (tree->funcName) - { - tree->opval.val->sym->type = newLink (DECLARATOR); - DCL_TYPE (tree->opval.val->sym->type) = FUNCTION; - tree->opval.val->sym->type->next = - tree->opval.val->sym->etype = newIntLink (); - tree->opval.val->etype = tree->opval.val->etype; - tree->opval.val->type = tree->opval.val->sym->type; - werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC, - tree->opval.val->sym->name); - //tree->opval.val->sym->undefined = 1; - allocVariables (tree->opval.val->sym); - } - else - { - tree->opval.val->sym->undefined = 1; - tree->opval.val->type = - tree->opval.val->etype = newIntLink (); - tree->opval.val->sym->type = - tree->opval.val->sym->etype = newIntLink (); - } - } + { + + /* if this is a function name then */ + /* mark it as returning an int */ + if (tree->funcName) + { + tree->opval.val->sym->type = newLink (DECLARATOR); + DCL_TYPE (tree->opval.val->sym->type) = FUNCTION; + tree->opval.val->sym->type->next = + tree->opval.val->sym->etype = newIntLink (); + tree->opval.val->etype = tree->opval.val->etype; + tree->opval.val->type = tree->opval.val->sym->type; + werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC, + tree->opval.val->sym->name); + //tree->opval.val->sym->undefined = 1; + allocVariables (tree->opval.val->sym); + } + else + { + tree->opval.val->sym->undefined = 1; + tree->opval.val->type = + tree->opval.val->etype = newIntLink (); + tree->opval.val->sym->type = + tree->opval.val->sym->etype = newIntLink (); + } + } } resolveChildren: @@ -541,7 +627,7 @@ int setAstLineno (ast * tree, int lineno) /*-----------------------------------------------------------------*/ symbol * funcOfType (char *name, sym_link * type, sym_link * argType, - int nArgs, int rent) + int nArgs, int rent) { symbol *sym; /* create the symbol */ @@ -561,18 +647,18 @@ funcOfType (char *name, sym_link * type, sym_link * argType, args = FUNC_ARGS(sym->type) = newValue (); while (nArgs--) - { - args->type = copyLinkChain (argType); - args->etype = getSpec (args->type); - SPEC_EXTR(args->etype)=1; - if (!nArgs) - break; - args = args->next = newValue (); - } + { + args->type = copyLinkChain (argType); + args->etype = getSpec (args->type); + SPEC_EXTR(args->etype)=1; + if (!nArgs) + break; + args = args->next = newValue (); + } } /* save it */ - addSymChain (sym); + addSymChain (&sym); sym->cdef = 1; allocVariables (sym); return sym; @@ -585,34 +671,34 @@ funcOfType (char *name, sym_link * type, sym_link * argType, symbol * funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes) { - + symbol *sym; int i ; /* create the symbol */ sym = newSymbol (name, 0); - + /* setup return value */ sym->type = newLink (DECLARATOR); DCL_TYPE (sym->type) = FUNCTION; sym->type->next = typeFromStr(rtype); sym->etype = getSpec (sym->type); - + /* if arguments required */ if (nArgs) { - value *args; - args = FUNC_ARGS(sym->type) = newValue (); - - for ( i = 0 ; i < nArgs ; i++ ) { - args->type = typeFromStr(atypes[i]); - args->etype = getSpec (args->type); - SPEC_EXTR(args->etype)=1; - if ((i + 1) == nArgs) break; - args = args->next = newValue (); - } + value *args; + args = FUNC_ARGS(sym->type) = newValue (); + + for ( i = 0 ; i < nArgs ; i++ ) { + args->type = typeFromStr(atypes[i]); + args->etype = getSpec (args->type); + SPEC_EXTR(args->etype)=1; + if ((i + 1) == nArgs) break; + args = args->next = newValue (); + } } /* save it */ - addSymChain (sym); + addSymChain (&sym); sym->cdef = 1; allocVariables (sym); return sym; @@ -630,11 +716,25 @@ reverseParms (ast * ptree) return; /* top down if we find a nonParm tree then quit */ - if (ptree->type == EX_OP && ptree->opval.op == PARAM) + if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed) { + /* The various functions expect the parameter tree to be right heavy. */ + /* Rotate the tree to be left heavy so that after reversal it is */ + /* right heavy again. */ + while ((ttree = ptree->right) && ttree->type == EX_OP && + ttree->opval.op == PARAM) + { + ptree->right = ttree->right; + ttree->right = ttree->left; + ttree->left = ptree->left; + ptree->left = ttree; + } + + /* Now reverse */ ttree = ptree->left; ptree->left = ptree->right; ptree->right = ttree; + ptree->reversed = 1; reverseParms (ptree->left); reverseParms (ptree->right); } @@ -648,14 +748,14 @@ reverseParms (ast * ptree) /*-----------------------------------------------------------------*/ static int processParms (ast *func, - value *defParm, - ast **actParm, - int *parmNumber, /* unused, although updated */ - bool rightmost) + value *defParm, + ast **actParm, + int *parmNumber, /* unused, although updated */ + bool rightmost) { RESULT_TYPE resultType; sym_link *functype; - + /* if none of them exist */ if (!defParm && !*actParm) return 0; @@ -674,15 +774,19 @@ processParms (ast *func, functype = func->ftype->next; else functype = func->ftype; - + /* if the function is being called via a pointer & */ /* it has not been defined a reentrant then we cannot */ /* have parameters */ - if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto) + /* PIC16 port can... */ + if (!TARGET_IS_PIC16) { - werror (W_NONRENT_ARGS); - fatalError++; - return 1; + if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto) + { + werror (W_NONRENT_ARGS); + fatalError++; + return 1; + } } /* if defined parameters ended but actual parameters */ @@ -705,9 +809,9 @@ processParms (ast *func, { (*actParm)->decorated = 1; return (processParms (func, defParm, - &(*actParm)->left, parmNumber, FALSE) || - processParms (func, defParm ? defParm->next : NULL, - &(*actParm)->right, parmNumber, rightmost)); + &(*actParm)->left, parmNumber, FALSE) || + processParms (func, defParm ? defParm->next : NULL, + &(*actParm)->right, parmNumber, rightmost)); } else if (defParm) /* not vararg */ { @@ -718,14 +822,14 @@ processParms (ast *func, * supply enough. */ if (rightmost && defParm->next) - { - werror (E_TOO_FEW_PARMS); - return 1; - } + { + werror (E_TOO_FEW_PARMS); + return 1; + } } /* decorate parameter */ - resultType = defParm ? getResultTypeFromType (defParm->etype) : + resultType = defParm ? getResultTypeFromType (defParm->type) : RESULT_TYPE_NONE; *actParm = decorateType (*actParm, resultType); @@ -742,40 +846,40 @@ processParms (ast *func, sym_link *ftype; if (IS_CAST_OP (*actParm) - || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast)) - { - /* Parameter was explicitly typecast; don't touch it. */ - return 0; - } + || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast)) + { + /* Parameter was explicitly typecast; don't touch it. */ + return 0; + } ftype = (*actParm)->ftype; /* If it's a char, upcast to int. */ if (IS_INTEGRAL (ftype) - && (getSize (ftype) < (unsigned) INTSIZE)) - { - newType = newAst_LINK(INTTYPE); - } + && (getSize (ftype) < (unsigned) INTSIZE)) + { + newType = newAst_LINK(INTTYPE); + } if (IS_PTR(ftype) && !IS_GENPTR(ftype)) - { - newType = newAst_LINK (copyLinkChain(ftype)); - DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer; - } + { + newType = newAst_LINK (copyLinkChain(ftype)); + DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer; + } if (IS_AGGREGATE (ftype)) - { - newType = newAst_LINK (copyLinkChain (ftype)); - DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer; - } - + { + newType = newAst_LINK (copyLinkChain (ftype)); + DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer; + } + if (newType) { /* cast required; change this op to a cast. */ (*actParm)->decorated = 0; *actParm = newNode (CAST, newType, *actParm); (*actParm)->lineno = (*actParm)->right->lineno; - + decorateType (*actParm, RESULT_TYPE_NONE); } return 0; @@ -788,7 +892,7 @@ processParms (ast *func, return 0; resolveSymbols (*actParm); - + /* the parameter type must be at least castable */ if (compareType (defParm->type, (*actParm)->ftype) == 0) { @@ -804,7 +908,7 @@ processParms (ast *func, resultType = getResultTypeFromType (defParm->etype); pTree = resolveSymbols (copyAst (*actParm)); - + /* now change the current one to a cast */ (*actParm)->type = EX_OP; (*actParm)->opval.op = CAST; @@ -834,15 +938,15 @@ createIvalType (ast * sym, sym_link * type, initList * ilist) if (ilist->type == INIT_DEEP) ilist = ilist->init.deep; - iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK); - return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK); + iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE); + return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE); } /*-----------------------------------------------------------------*/ /* createIvalStruct - generates initial value for structures */ /*-----------------------------------------------------------------*/ static ast * -createIvalStruct (ast * sym, sym_link * type, initList * ilist) +createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue) { ast *rast = NULL; ast *lAst; @@ -862,17 +966,20 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist) { /* if we have come to end */ if (!iloop) - break; + break; sflds->implicit = 1; lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds))); - lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK); - rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK); + lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE); + rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, + iloop, rast, rootValue)), + RESULT_TYPE_NONE); + } if (iloop) { werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef, - W_EXCESS_INITIALIZERS, "struct", - sym->opval.val->sym->name); + W_EXCESS_INITIALIZERS, "struct", + sym->opval.val->sym->name); } return rast; @@ -883,7 +990,7 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist) /* createIvalArray - generates code for array initialization */ /*-----------------------------------------------------------------*/ static ast * -createIvalArray (ast * sym, sym_link * type, initList * ilist) +createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue) { ast *rast = NULL; initList *iloop; @@ -895,84 +1002,89 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) /* by a string */ if (IS_CHAR (type->next)) if ((rast = createIvalCharPtr (sym, - type, - decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK)))) + type, + decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE), + rootValue))) - return decorateType (resolveSymbols (rast), RESULT_CHECK); + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); - /* not the special case */ - if (ilist->type != INIT_DEEP) - { - werror (E_INIT_STRUCT, ""); - return NULL; - } + /* not the special case */ + if (ilist->type != INIT_DEEP) + { + werror (E_INIT_STRUCT, ""); + return NULL; + } - iloop = ilist->init.deep; - lcnt = DCL_ELEM (type); + iloop = ilist->init.deep; + lcnt = DCL_ELEM (type); - if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL)) - { - ast *aSym; - - aSym = decorateType (resolveSymbols(sym), RESULT_CHECK); - - rast = newNode(ARRAYINIT, aSym, NULL); - rast->values.constlist = literalL; - - // Make sure size is set to length of initializer list. - while (iloop) - { - size++; - iloop = iloop->next; - } - - if (lcnt && size > lcnt) - { - // Array size was specified, and we have more initializers than needed. - char *name=sym->opval.val->sym->name; - int lineno=sym->opval.val->sym->lineDef; - char *filename=sym->opval.val->sym->fileDef; - - werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); - } - } - else - { - for (;;) - { - ast *aSym; - - aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++)))); - aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK); - rast = createIval (aSym, type->next, iloop, rast); - iloop = (iloop ? iloop->next : NULL); - if (!iloop) - { - break; - } - - /* no of elements given and we */ - /* have generated for all of them */ - if (!--lcnt) - { - // there has to be a better way - char *name=sym->opval.val->sym->name; - int lineno=sym->opval.val->sym->lineDef; - char *filename=sym->opval.val->sym->fileDef; - werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); - - break; - } - } - } + if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL)) + { + ast *aSym; + + aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE); + + rast = newNode(ARRAYINIT, aSym, NULL); + rast->values.constlist = literalL; + + // Make sure size is set to length of initializer list. + while (iloop) + { + size++; + iloop = iloop->next; + } + + if (lcnt && size > lcnt) + { + // Array size was specified, and we have more initializers than needed. + char *name=sym->opval.val->sym->name; + int lineno=sym->opval.val->sym->lineDef; + char *filename=sym->opval.val->sym->fileDef; + + werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); + } + } + else + { + for (;;) + { + ast *aSym; + + aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++)))); + aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE); + rast = createIval (aSym, type->next, iloop, rast, rootValue); + iloop = (iloop ? iloop->next : NULL); + if (!iloop) + { + break; + } + + /* no of elements given and we */ + /* have generated for all of them */ + if (!--lcnt) + { + // is this a better way? at least it won't crash + char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : ""; + int lineno = iloop->lineno; + char *filename = iloop->filename; + werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); + + break; + } + } + } - /* if we have not been given a size */ - if (!DCL_ELEM (type)) + /* if we have not been given a size */ + if (!DCL_ELEM (type)) { - DCL_ELEM (type) = size; + /* check, if it's a flexible array */ + if (IS_STRUCT (AST_VALUE (rootValue)->type)) + AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next); + else + DCL_ELEM (type) = size; } - return decorateType (resolveSymbols (rast), RESULT_CHECK); + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); } @@ -980,15 +1092,16 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) /* createIvalCharPtr - generates initial values for char pointers */ /*-----------------------------------------------------------------*/ static ast * -createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) +createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal) { ast *rast = NULL; + unsigned size = 0; /* if this is a pointer & right is a literal array then */ /* just assignment will do */ if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) || - SPEC_SCLS (iexpr->etype) == S_CODE) - && IS_ARRAY (iexpr->ftype))) + SPEC_SCLS (iexpr->etype) == S_CODE) + && IS_ARRAY (iexpr->ftype))) return newNode ('=', sym, iexpr); /* left side is an array so we have to assign each */ @@ -1000,33 +1113,47 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) /* for each character generate an assignment */ /* to the array element */ char *s = SPEC_CVAL (iexpr->etype).v_char; - int i = 0; - int size = getSize (iexpr->ftype); - int symsize = getSize (type); - - if (size>symsize) - { - if (size>(symsize+1)) - werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS, - "string", sym->opval.val->sym->name); - size = symsize; - } + unsigned int i = 0; + unsigned int symsize = getSize (type); + + size = getSize (iexpr->ftype); + if (symsize && size>symsize) + { + if (size>(symsize+1)) + { + char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : ""; + + werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS, + "string", name); + } + size = symsize; + } for (i=0;itype)) + AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next); + else + DCL_ELEM (type) = size; + } + + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); } return NULL; @@ -1036,7 +1163,7 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) /* createIvalPtr - generates initial value for pointers */ /*-----------------------------------------------------------------*/ static ast * -createIvalPtr (ast * sym, sym_link * type, initList * ilist) +createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal) { ast *rast; ast *iexpr; @@ -1045,11 +1172,11 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist) if (ilist->type == INIT_DEEP) ilist = ilist->init.deep; - iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK); + iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE); /* if character pointer */ if (IS_CHAR (type->next)) - if ((rast = createIvalCharPtr (sym, type, iexpr))) + if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal))) return rast; return newNode ('=', sym, iexpr); @@ -1059,7 +1186,7 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist) /* createIval - generates code for initial value */ /*-----------------------------------------------------------------*/ static ast * -createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) +createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue) { ast *rast = NULL; @@ -1068,31 +1195,32 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) /* if structure then */ if (IS_STRUCT (type)) - rast = createIvalStruct (sym, type, ilist); + rast = createIvalStruct (sym, type, ilist, rootValue); else /* if this is a pointer */ if (IS_PTR (type)) - rast = createIvalPtr (sym, type, ilist); + rast = createIvalPtr (sym, type, ilist, rootValue); else /* if this is an array */ if (IS_ARRAY (type)) - rast = createIvalArray (sym, type, ilist); + rast = createIvalArray (sym, type, ilist, rootValue); else /* if type is SPECIFIER */ if (IS_SPEC (type)) rast = createIvalType (sym, type, ilist); if (wid) - return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK); + return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE); else - return decorateType (resolveSymbols (rast), RESULT_CHECK); + return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); } /*-----------------------------------------------------------------*/ /* initAggregates - initialises aggregate variables with initv */ /*-----------------------------------------------------------------*/ ast * initAggregates (symbol * sym, initList * ival, ast * wid) { - return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid); + ast *newAst = newAst_VALUE (symbolVal (sym)); + return createIval (newAst, sym->type, ival, wid, newAst); } /*-----------------------------------------------------------------*/ @@ -1112,80 +1240,95 @@ gatherAutoInit (symbol * autoChain) /* resolve the symbols in the ival */ if (sym->ival) - resolveIvalSym (sym->ival, sym->type); + resolveIvalSym (sym->ival, sym->type); + +#if 1 + /* if we are PIC16 port, + * and this is a static, + * and have initial value, + * and not S_CODE, don't emit in gs segment, + * but allow glue.c:pic16emitRegularMap to put symbol + * in idata section */ + if(TARGET_IS_PIC16 && + IS_STATIC (sym->etype) && sym->ival + && SPEC_SCLS(sym->etype) != S_CODE) { + SPEC_SCLS (sym->etype) = S_DATA; + continue; + } +#endif /* if this is a static variable & has an */ /* initial value the code needs to be lifted */ /* here to the main portion since they can be */ /* initialised only once at the start */ if (IS_STATIC (sym->etype) && sym->ival && - SPEC_SCLS (sym->etype) != S_CODE) - { - symbol *newSym; - - /* insert the symbol into the symbol table */ - /* with level = 0 & name = rname */ - newSym = copySymbol (sym); - addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1); - - /* now lift the code to main */ - if (IS_AGGREGATE (sym->type)) { - work = initAggregates (sym, sym->ival, NULL); - } else { - if (getNelements(sym->type, sym->ival)>1) { - werrorfl (sym->fileDef, sym->lineDef, - W_EXCESS_INITIALIZERS, "scalar", - sym->name); - } - work = newNode ('=', newAst_VALUE (symbolVal (newSym)), - list2expr (sym->ival)); - } - - setAstLineno (work, sym->lineDef); - - sym->ival = NULL; - if (staticAutos) - staticAutos = newNode (NULLOP, staticAutos, work); - else - staticAutos = work; - - continue; - } + SPEC_SCLS (sym->etype) != S_CODE) + { + symbol *newSym; + + /* insert the symbol into the symbol table */ + /* with level = 0 & name = rname */ + newSym = copySymbol (sym); + addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1); + + /* now lift the code to main */ + if (IS_AGGREGATE (sym->type)) { + work = initAggregates (sym, sym->ival, NULL); + } else { + if (getNelements(sym->type, sym->ival)>1) { + werrorfl (sym->fileDef, sym->lineDef, + W_EXCESS_INITIALIZERS, "scalar", + sym->name); + } + work = newNode ('=', newAst_VALUE (symbolVal (newSym)), + list2expr (sym->ival)); + } + + setAstLineno (work, sym->lineDef); + + sym->ival = NULL; + if (staticAutos) + staticAutos = newNode (NULLOP, staticAutos, work); + else + staticAutos = work; + + continue; + } /* if there is an initial value */ if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE) - { - initList *ilist=sym->ival; - - while (ilist->type == INIT_DEEP) { - ilist = ilist->init.deep; - } - - /* update lineno for error msg */ - lineno=sym->lineDef; - setAstLineno (ilist->init.node, lineno); - - if (IS_AGGREGATE (sym->type)) { - work = initAggregates (sym, sym->ival, NULL); - } else { - if (getNelements(sym->type, sym->ival)>1) { - werrorfl (sym->fileDef, sym->lineDef, - W_EXCESS_INITIALIZERS, "scalar", - sym->name); - } - work = newNode ('=', newAst_VALUE (symbolVal (sym)), - list2expr (sym->ival)); - } - - // just to be sure - setAstLineno (work, sym->lineDef); - - sym->ival = NULL; - if (init) - init = newNode (NULLOP, init, work); - else - init = work; - } + { + initList *ilist=sym->ival; + + while (ilist->type == INIT_DEEP) { + ilist = ilist->init.deep; + } + + /* update lineno for error msg */ + lineno=sym->lineDef; + setAstLineno (ilist->init.node, lineno); + + if (IS_AGGREGATE (sym->type)) { + work = initAggregates (sym, sym->ival, NULL); + } else { + if (getNelements(sym->type, sym->ival)>1) { + werrorfl (sym->fileDef, sym->lineDef, + W_EXCESS_INITIALIZERS, "scalar", + sym->name); + } + work = newNode ('=', newAst_VALUE (symbolVal (sym)), + list2expr (sym->ival)); + } + + // just to be sure + setAstLineno (work, sym->lineDef); + + sym->ival = NULL; + if (init) + init = newNode (NULLOP, init, work); + else + init = work; + } } inInitMode = 0; return init; @@ -1204,7 +1347,7 @@ void freeStringSymbol(symbol *sym) { } } } - + /*-----------------------------------------------------------------*/ /* stringToSymbol - creates a symbol from a literal string */ /*-----------------------------------------------------------------*/ @@ -1215,14 +1358,14 @@ stringToSymbol (value * val) static int charLbl = 0; symbol *sym; set *sp; - int size; + unsigned int size; // have we heard this before? for (sp=statsg->syms; sp; sp=sp->next) { sym=sp->item; size = getSize (sym->type); if (sym->isstrlit && size == getSize (val->type) && - !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) { + !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) { // yes, this is old news. Don't publish it again. sym->isstrlit++; // but raise the usage count return symbolVal(sym); @@ -1230,7 +1373,7 @@ stringToSymbol (value * val) } SNPRINTF (name, sizeof(name), "_str_%d", charLbl++); - sym = newSymbol (name, 0); /* make it @ level 0 */ + sym = newSymbol (name, 0); /* make it @ level 0 */ strncpyz (sym->rname, name, SDCC_NAME_MAX); /* copy the type from the value passed */ @@ -1248,7 +1391,7 @@ stringToSymbol (value * val) if (noAlloc == 0) { /* allocate it */ - addSymChain (sym); + addSymChain (&sym); allocVariables (sym); } sym->ival = NULL; @@ -1274,15 +1417,15 @@ processBlockVars (ast * tree, int *stack, int action) if (action == ALLOCATE) { - *stack += allocVariables (tree->values.sym); - autoInit = gatherAutoInit (tree->values.sym); - - /* if there are auto inits then do them */ - if (autoInit) - tree->left = newNode (NULLOP, autoInit, tree->left); + *stack += allocVariables (tree->values.sym); + autoInit = gatherAutoInit (tree->values.sym); + + /* if there are auto inits then do them */ + if (autoInit) + tree->left = newNode (NULLOP, autoInit, tree->left); } - else /* action is deallocate */ - deallocLocal (tree->values.sym); + else /* action is deallocate */ + deallocLocal (tree->values.sym); } processBlockVars (tree->left, stack, action); @@ -1301,55 +1444,55 @@ bool constExprTree (ast *cexpr) { return TRUE; } - cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK); + cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE); - switch (cexpr->type) + switch (cexpr->type) { case EX_VALUE: if (IS_AST_LIT_VALUE(cexpr)) { - // this is a literal - return TRUE; + // this is a literal + return TRUE; } if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) { - // a function's address will never change - return TRUE; + // a function's address will never change + return TRUE; } if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) { - // an array's address will never change - return TRUE; + // an array's address will never change + return TRUE; } - if (IS_AST_SYM_VALUE(cexpr) && - IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) { - // a symbol in code space will never change - // This is only for the 'char *s="hallo"' case and will have to leave + if (IS_AST_SYM_VALUE(cexpr) && + IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) { + // a symbol in code space will never change + // This is only for the 'char *s="hallo"' case and will have to leave //printf(" code space symbol"); - return TRUE; + return TRUE; } return FALSE; case EX_LINK: werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "unexpected link in expression tree\n"); + "unexpected link in expression tree\n"); return FALSE; case EX_OP: if (cexpr->opval.op==ARRAYINIT) { - // this is a list of literals - return TRUE; + // this is a list of literals + return TRUE; } if (cexpr->opval.op=='=') { - return constExprTree(cexpr->right); + return constExprTree(cexpr->right); } if (cexpr->opval.op==CAST) { - // cast ignored, maybe we should throw a warning here? - return constExprTree(cexpr->right); + // cast ignored, maybe we should throw a warning here? + return constExprTree(cexpr->right); } - if (cexpr->opval.op=='&') { - return TRUE; + if (cexpr->opval.op=='&') { + return TRUE; } if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) { - return FALSE; + return FALSE; } if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) { - return TRUE; + return TRUE; } return FALSE; case EX_OPERAND: @@ -1357,7 +1500,7 @@ bool constExprTree (ast *cexpr) { } return FALSE; } - + /*-----------------------------------------------------------------*/ /* constExprValue - returns the value of a constant expression */ /* or NULL if it is not a constant expression */ @@ -1365,7 +1508,7 @@ bool constExprTree (ast *cexpr) { value * constExprValue (ast * cexpr, int check) { - cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK); + cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE); /* if this is not a constant then */ if (!IS_LITERAL (cexpr->ftype)) @@ -1373,47 +1516,50 @@ constExprValue (ast * cexpr, int check) /* then check if this is a literal array in code segment */ if (SPEC_SCLS (cexpr->etype) == S_CODE && - SPEC_CVAL (cexpr->etype).v_char && - IS_ARRAY (cexpr->ftype)) - { - value *val = valFromType (cexpr->ftype); - SPEC_SCLS (val->etype) = S_LITERAL; - val->sym = cexpr->opval.val->sym; - val->sym->type = copyLinkChain (cexpr->ftype); - val->sym->etype = getSpec (val->sym->type); - strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX); - return val; - } + SPEC_CVAL (cexpr->etype).v_char && + IS_ARRAY (cexpr->ftype)) + { + value *val = valFromType (cexpr->ftype); + SPEC_SCLS (val->etype) = S_LITERAL; + val->sym = cexpr->opval.val->sym; + val->sym->type = copyLinkChain (cexpr->ftype); + val->sym->etype = getSpec (val->sym->type); + strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX); + return val; + } /* if we are casting a literal value then */ if (IS_AST_OP (cexpr) && - cexpr->opval.op == CAST && - IS_LITERAL (cexpr->right->ftype)) + cexpr->opval.op == CAST && + IS_LITERAL (cexpr->right->ftype)) { - return valCastLiteral (cexpr->ftype, - floatFromVal (cexpr->right->opval.val)); + return valCastLiteral (cexpr->ftype, + floatFromVal (cexpr->right->opval.val)); } if (IS_AST_VALUE (cexpr)) { - return cexpr->opval.val; + return cexpr->opval.val; } if (check) - werror (E_CONST_EXPECTED, "found expression"); + werror (E_CONST_EXPECTED, "found expression"); return NULL; } /* return the value */ - return cexpr->opval.val; - + if (IS_AST_VALUE (cexpr)) + { + return cexpr->opval.val; + } + return NULL; } /*-----------------------------------------------------------------*/ /* isLabelInAst - will return true if a given label is found */ /*-----------------------------------------------------------------*/ -bool +bool isLabelInAst (symbol * label, ast * tree) { if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree)) @@ -1433,9 +1579,9 @@ isLabelInAst (symbol * label, ast * tree) /* isLoopCountable - return true if the loop count can be determi- */ /* -ned at compile time . */ /*-----------------------------------------------------------------*/ -bool +static bool isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, - symbol ** sym, ast ** init, ast ** end) + symbol ** sym, ast ** init, ast ** end) { /* the loop is considered countable if the following @@ -1448,9 +1594,9 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, /* first check the initExpr */ if (IS_AST_OP (initExpr) && - initExpr->opval.op == '=' && /* is assignment */ + initExpr->opval.op == '=' && /* is assignment */ IS_AST_SYM_VALUE (initExpr->left)) - { /* left is a symbol */ + { /* left is a symbol */ *sym = AST_SYMBOL (initExpr->left); *init = initExpr->right; @@ -1458,6 +1604,10 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, else return FALSE; + /* don't reverse loop with volatile counter */ + if (IS_VOLATILE ((*sym)->type)) + return FALSE; + /* for now the symbol has to be of integral type */ if (!IS_INTEGRAL ((*sym)->type)) @@ -1468,36 +1618,38 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, { switch (condExpr->opval.op) - { - case '<': - if (IS_AST_SYM_VALUE (condExpr->left) && - isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) && - IS_AST_LIT_VALUE (condExpr->right)) - { - *end = condExpr->right; - break; - } - return FALSE; - - case '!': - if (IS_AST_OP (condExpr->left) && - condExpr->left->opval.op == '>' && - IS_AST_LIT_VALUE (condExpr->left->right) && - IS_AST_SYM_VALUE (condExpr->left->left) && - isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left))) - { - - *end = newNode ('+', condExpr->left->right, - newAst_VALUE (constVal ("1"))); - break; - } - return FALSE; - - default: - return FALSE; - } + { + case '<': + if (IS_AST_SYM_VALUE (condExpr->left) && + isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) && + IS_AST_LIT_VALUE (condExpr->right)) + { + *end = condExpr->right; + break; + } + return FALSE; + + case '!': + if (IS_AST_OP (condExpr->left) && + condExpr->left->opval.op == '>' && + IS_AST_LIT_VALUE (condExpr->left->right) && + IS_AST_SYM_VALUE (condExpr->left->left) && + isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left))) + { + + *end = newNode ('+', condExpr->left->right, + newAst_VALUE (constVal ("1"))); + break; + } + return FALSE; + + default: + return FALSE; + } } + else + return FALSE; /* check loop expression is of the form ++ */ if (!IS_AST_OP (loopExpr)) @@ -1508,34 +1660,34 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, { if (loopExpr->left) - { - /* pre */ - if (IS_AST_SYM_VALUE (loopExpr->left) && - isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left))) - return TRUE; + { + /* pre */ + if (IS_AST_SYM_VALUE (loopExpr->left) && + isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left))) + return TRUE; - } + } else - { - /* post */ - if (IS_AST_SYM_VALUE (loopExpr->right) && - isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right))) - return TRUE; - } + { + /* post */ + if (IS_AST_SYM_VALUE (loopExpr->right) && + isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right))) + return TRUE; + } } else { /* check for += */ if (loopExpr->opval.op == ADD_ASSIGN) - { - - if (IS_AST_SYM_VALUE (loopExpr->left) && - isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) && - IS_AST_LIT_VALUE (loopExpr->right) && - (int) AST_LIT_VALUE (loopExpr->right) != 1) - return TRUE; - } + { + + if (IS_AST_SYM_VALUE (loopExpr->left) && + isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) && + IS_AST_LIT_VALUE (loopExpr->right) && + (int) AST_LIT_VALUE (loopExpr->right) != 1) + return TRUE; + } } return FALSE; @@ -1544,7 +1696,7 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, /*-----------------------------------------------------------------*/ /* astHasVolatile - returns true if ast contains any volatile */ /*-----------------------------------------------------------------*/ -bool +bool astHasVolatile (ast * tree) { if (!tree) @@ -1563,7 +1715,7 @@ astHasVolatile (ast * tree) /*-----------------------------------------------------------------*/ /* astHasPointer - return true if the ast contains any ptr variable */ /*-----------------------------------------------------------------*/ -bool +bool astHasPointer (ast * tree) { if (!tree) @@ -1588,7 +1740,7 @@ astHasPointer (ast * tree) /*-----------------------------------------------------------------*/ /* astHasSymbol - return true if the ast has the given symbol */ /*-----------------------------------------------------------------*/ -bool +bool astHasSymbol (ast * tree, symbol * sym) { if (!tree || IS_AST_LINK (tree)) @@ -1597,9 +1749,9 @@ astHasSymbol (ast * tree, symbol * sym) if (IS_AST_VALUE (tree)) { if (IS_AST_SYM_VALUE (tree)) - return isSymbolEqual (AST_SYMBOL (tree), sym); + return isSymbolEqual (AST_SYMBOL (tree), sym); else - return FALSE; + return FALSE; } return astHasSymbol (tree->left, sym) || @@ -1609,14 +1761,14 @@ astHasSymbol (ast * tree, symbol * sym) /*-----------------------------------------------------------------*/ /* astHasDeref - return true if the ast has an indirect access */ /*-----------------------------------------------------------------*/ -static bool +static bool astHasDeref (ast * tree) { if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree)) return FALSE; if (tree->opval.op == '*' && tree->right == NULL) return TRUE; - + return astHasDeref (tree->left) || astHasDeref (tree->right); } @@ -1624,7 +1776,7 @@ astHasDeref (ast * tree) /* isConformingBody - the loop body has to conform to a set of rules */ /* for the loop to be considered reversible read on for rules */ /*-----------------------------------------------------------------*/ -bool +bool isConformingBody (ast * pbody, symbol * sym, ast * body) { @@ -1643,7 +1795,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /* if we reach the end or a leaf then true */ if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody)) return TRUE; - + /* if anything else is "volatile" */ if (IS_VOLATILE (TETYPE (pbody))) return FALSE; @@ -1655,10 +1807,12 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /*------------------------------------------------------------------*/ case '[': // if the loopvar is used as an index - if (astHasSymbol(pbody->right, sym)) { - return FALSE; + /* array op is commutative -- must check both left & right */ + if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) { + return FALSE; } - return isConformingBody (pbody->right, sym, body); + return isConformingBody (pbody->right, sym, body) + && isConformingBody (pbody->left, sym, body); /*------------------------------------------------------------------*/ case PTR_OP: @@ -1671,20 +1825,20 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /* sure we are not sym is not modified */ if (pbody->left && - IS_AST_SYM_VALUE (pbody->left) && - isSymbolEqual (AST_SYMBOL (pbody->left), sym)) - return FALSE; + IS_AST_SYM_VALUE (pbody->left) && + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; if (pbody->right && - IS_AST_SYM_VALUE (pbody->right) && - isSymbolEqual (AST_SYMBOL (pbody->right), sym)) - return FALSE; + IS_AST_SYM_VALUE (pbody->right) && + isSymbolEqual (AST_SYMBOL (pbody->right), sym)) + return FALSE; return TRUE; /*------------------------------------------------------------------*/ - case '*': /* can be unary : if right is null then unary operation */ + case '*': /* can be unary : if right is null then unary operation */ case '+': case '-': case '&': @@ -1695,19 +1849,19 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /* address of */ /*----------------------------*/ if (!pbody->right) - { - if (IS_AST_SYM_VALUE (pbody->left) && - isSymbolEqual (AST_SYMBOL (pbody->left), sym)) - return FALSE; - else - return isConformingBody (pbody->left, sym, body); - } + { + if (IS_AST_SYM_VALUE (pbody->left) && + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; + else + return isConformingBody (pbody->left, sym, body); + } else - { - if (astHasSymbol (pbody->left, sym) || - astHasSymbol (pbody->right, sym)) - return FALSE; - } + { + if (astHasSymbol (pbody->left, sym) || + astHasSymbol (pbody->right, sym)) + return FALSE; + } /*------------------------------------------------------------------*/ @@ -1717,17 +1871,20 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) case '%': case LEFT_OP: case RIGHT_OP: + case GETABIT: + case GETBYTE: + case GETWORD: if (IS_AST_SYM_VALUE (pbody->left) && - isSymbolEqual (AST_SYMBOL (pbody->left), sym)) - return FALSE; + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; if (IS_AST_SYM_VALUE (pbody->right) && - isSymbolEqual (AST_SYMBOL (pbody->right), sym)) - return FALSE; + isSymbolEqual (AST_SYMBOL (pbody->right), sym)) + return FALSE; return isConformingBody (pbody->left, sym, body) && - isConformingBody (pbody->right, sym, body); + isConformingBody (pbody->right, sym, body); case '~': case '!': @@ -1736,8 +1893,8 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) case GETHBIT: case SWAP: if (IS_AST_SYM_VALUE (pbody->left) && - isSymbolEqual (AST_SYMBOL (pbody->left), sym)) - return FALSE; + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; return isConformingBody (pbody->left, sym, body); /*------------------------------------------------------------------*/ @@ -1752,18 +1909,18 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) case NE_OP: case '?': case ':': - case SIZEOF: /* evaluate wihout code generation */ + case SIZEOF: /* evaluate wihout code generation */ if (IS_AST_SYM_VALUE (pbody->left) && - isSymbolEqual (AST_SYMBOL (pbody->left), sym)) - return FALSE; + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; if (IS_AST_SYM_VALUE (pbody->right) && - isSymbolEqual (AST_SYMBOL (pbody->right), sym)) - return FALSE; + isSymbolEqual (AST_SYMBOL (pbody->right), sym)) + return FALSE; return isConformingBody (pbody->left, sym, body) && - isConformingBody (pbody->right, sym, body); + isConformingBody (pbody->right, sym, body); /*------------------------------------------------------------------*/ case '=': @@ -1771,29 +1928,29 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /* if left has a pointer & right has loop control variable then we cannot */ if (astHasPointer (pbody->left) && - astHasSymbol (pbody->right, sym)) - return FALSE; + astHasSymbol (pbody->right, sym)) + return FALSE; if (astHasVolatile (pbody->left)) - return FALSE; + return FALSE; if (IS_AST_SYM_VALUE (pbody->left)) { - // if the loopvar has an assignment - if (isSymbolEqual (AST_SYMBOL (pbody->left), sym)) - return FALSE; - // if the loopvar is used in another (maybe conditional) block - if (astHasSymbol (pbody->right, sym) && - (pbody->level >= body->level)) { - return FALSE; - } + // if the loopvar has an assignment + if (isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; + // if the loopvar is used in another (maybe conditional) block + if (astHasSymbol (pbody->right, sym) && + (pbody->level >= body->level)) { + return FALSE; + } } if (astHasVolatile (pbody->left)) - return FALSE; + return FALSE; if (astHasDeref(pbody->right)) return FALSE; return isConformingBody (pbody->left, sym, body) && - isConformingBody (pbody->right, sym, body); + isConformingBody (pbody->right, sym, body); case MUL_ASSIGN: case DIV_ASSIGN: @@ -1812,16 +1969,16 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /*----------------------------*/ case ',': return isConformingBody (pbody->left, sym, body) && - isConformingBody (pbody->right, sym, body); + isConformingBody (pbody->right, sym, body); /*------------------------------------------------------------------*/ /*----------------------------*/ /* function call */ /*----------------------------*/ case CALL: - /* if local & not passed as paramater then ok */ - if (sym->level && !astHasSymbol(pbody->right,sym)) - return TRUE; + /* if local & not passed as paramater then ok */ + if (sym->level && !astHasSymbol(pbody->right,sym)) + return TRUE; return FALSE; /*------------------------------------------------------------------*/ @@ -1833,12 +1990,12 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) case GOTO: if (isLabelInAst (AST_SYMBOL (pbody->left), body)) - return TRUE; + return TRUE; else - return FALSE; + return FALSE; case SWITCH: if (astHasSymbol (pbody->left, sym)) - return FALSE; + return FALSE; default: break; @@ -1856,9 +2013,9 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /* if the for loop is reversible. If yes will set the value of */ /* the loop control var & init value & termination value */ /*-----------------------------------------------------------------*/ -bool +static bool isLoopReversible (ast * loop, symbol ** loopCntrl, - ast ** init, ast ** end) + ast ** init, ast ** end) { /* if option says don't do it then don't */ if (optimize.noLoopReverse) @@ -1871,9 +2028,9 @@ isLoopReversible (ast * loop, symbol ** loopCntrl, [++] | [ += 1] | [ = + 1] ) forBody */ if (!isLoopCountable (AST_FOR (loop, initExpr), - AST_FOR (loop, condExpr), - AST_FOR (loop, loopExpr), - loopCntrl, init, end)) + AST_FOR (loop, condExpr), + AST_FOR (loop, loopExpr), + loopCntrl, init, end)) return 0; /* now do some serious checking on the body of the loop @@ -1886,7 +2043,7 @@ isLoopReversible (ast * loop, symbol ** loopCntrl, /*-----------------------------------------------------------------*/ /* replLoopSym - replace the loop sym by loop sym -1 */ /*-----------------------------------------------------------------*/ -static void +static void replLoopSym (ast * body, symbol * sym) { /* reached end */ @@ -1897,14 +2054,14 @@ replLoopSym (ast * body, symbol * sym) { if (isSymbolEqual (AST_SYMBOL (body), sym)) - { + { - body->type = EX_OP; - body->opval.op = '-'; - body->left = newAst_VALUE (symbolVal (sym)); - body->right = newAst_VALUE (constVal ("1")); + body->type = EX_OP; + body->opval.op = '-'; + body->left = newAst_VALUE (symbolVal (sym)); + body->right = newAst_VALUE (constVal ("1")); - } + } return; @@ -1933,32 +2090,32 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) /* put it together piece by piece */ rloop = newNode (NULLOP, - createIf (newAst_VALUE (symbolVal (sym)), - newNode (GOTO, - newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))), - NULL), NULL), - newNode ('=', - newAst_VALUE (symbolVal (sym)), - end)); + createIf (newAst_VALUE (symbolVal (sym)), + newNode (GOTO, + newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))), + NULL), NULL), + newNode ('=', + newAst_VALUE (symbolVal (sym)), + end)); replLoopSym (loop->left, sym); setAstLineno (rloop, init->lineno); rloop = newNode (NULLOP, - newNode ('=', - newAst_VALUE (symbolVal (sym)), - newNode ('-', end, init)), - createLabel (AST_FOR (loop, continueLabel), - newNode (NULLOP, - loop->left, - newNode (NULLOP, - newNode (SUB_ASSIGN, - newAst_VALUE (symbolVal (sym)), - newAst_VALUE (constVal ("1"))), - rloop)))); + newNode ('=', + newAst_VALUE (symbolVal (sym)), + newNode ('-', end, init)), + createLabel (AST_FOR (loop, continueLabel), + newNode (NULLOP, + loop->left, + newNode (NULLOP, + newNode (SUB_ASSIGN, + newAst_VALUE (symbolVal (sym)), + newAst_VALUE (constVal ("1"))), + rloop)))); rloop->lineno=init->lineno; - return decorateType (rloop, RESULT_CHECK); + return decorateType (rloop, RESULT_TYPE_NONE); } @@ -1977,36 +2134,36 @@ searchLitOp (ast *tree, ast **parent, const char *ops) IS_AST_OP(tree->right) && tree->right->right && (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1])) - { - if (IS_LITERAL (RTYPE (tree->right)) != - IS_LITERAL (LTYPE (tree->right))) - { - tree->right->decorated = 0; - tree->decorated = 0; - *parent = tree; - return tree->right; - } - ret = searchLitOp (tree->right, parent, ops); - if (ret) - return ret; + { + if (IS_LITERAL (RTYPE (tree->right)) != + IS_LITERAL (LTYPE (tree->right))) + { + tree->right->decorated = 0; + tree->decorated = 0; + *parent = tree; + return tree->right; + } + ret = searchLitOp (tree->right, parent, ops); + if (ret) + return ret; } if (tree->left && IS_AST_OP(tree->left) && tree->left->right && - (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1])) - { - if (IS_LITERAL (RTYPE (tree->left)) != - IS_LITERAL (LTYPE (tree->left))) - { - tree->left->decorated = 0; - tree->decorated = 0; - *parent = tree; - return tree->left; - } - ret = searchLitOp (tree->left, parent, ops); - if (ret) - return ret; - } + (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1])) + { + if (IS_LITERAL (RTYPE (tree->left)) != + IS_LITERAL (LTYPE (tree->left))) + { + tree->left->decorated = 0; + tree->decorated = 0; + *parent = tree; + return tree->left; + } + ret = searchLitOp (tree->left, parent, ops); + if (ret) + return ret; + } } return NULL; } @@ -2023,7 +2180,7 @@ getResultTypeFromType (sym_link *type) if (IS_BITFIELD (type)) { int blen = SPEC_BLEN (type); - + if (blen <= 1) return RESULT_TYPE_BIT; if (blen <= 8) @@ -2042,53 +2199,67 @@ getResultTypeFromType (sym_link *type) /* addCast - adds casts to a type specified by RESULT_TYPE */ /*-----------------------------------------------------------------*/ static ast * -addCast (ast *tree, RESULT_TYPE resultType, bool upcast) +addCast (ast *tree, RESULT_TYPE resultType, bool promote) { sym_link *newLink; bool upCasted = FALSE; - + switch (resultType) { case RESULT_TYPE_NONE: - /* char: promote to int */ - if (!upcast || - getSize (tree->etype) >= INTSIZE) - return tree; - newLink = newIntLink(); - upCasted = TRUE; - break; + /* if thing smaller than int must be promoted to int */ + if (!promote || + getSize (tree->etype) >= INTSIZE) + /* promotion not necessary or already an int */ + return tree; + /* char and bits: promote to int */ + newLink = newIntLink(); + upCasted = TRUE; + break; + case RESULT_TYPE_BIT: + if (!promote || + /* already an int */ + bitsForType (tree->etype) >= 16 || + /* bit to bit operation: don't promote, the code generators + hopefully know everything about promotion rules */ + bitsForType (tree->etype) == 1) + return tree; + newLink = newIntLink(); + upCasted = TRUE; + break; case RESULT_TYPE_CHAR: - if (IS_CHAR (tree->etype) || - IS_FLOAT(tree->etype)) - return tree; - newLink = newCharLink(); - break; + if (IS_CHAR (tree->etype) || + IS_FLOAT(tree->etype) || + IS_FIXED(tree->etype)) + return tree; + newLink = newCharLink(); + break; case RESULT_TYPE_INT: #if 0 - if (getSize (tree->etype) > INTSIZE) + if (getSize (tree->etype) > INTSIZE) { /* warn ("Loosing significant digits"); */ - return; - } + return; + } #endif - /* char: promote to int */ - if (!upcast || - getSize (tree->etype) >= INTSIZE) - return tree; - newLink = newIntLink(); - upCasted = TRUE; - break; + /* char: promote to int */ + if (!promote || + getSize (tree->etype) >= INTSIZE) + return tree; + newLink = newIntLink(); + upCasted = TRUE; + break; case RESULT_TYPE_OTHER: - if (!upcast) - return tree; + if (!promote) + return tree; /* return type is long, float: promote char to int */ - if (getSize (tree->etype) >= INTSIZE) - return tree; - newLink = newIntLink(); - upCasted = TRUE; - break; + if (getSize (tree->etype) >= INTSIZE) + return tree; + newLink = newIntLink(); + upCasted = TRUE; + break; default: - return tree; + return tree; } tree->decorated = 0; tree = newNode (CAST, newAst_LINK (newLink), tree); @@ -2108,6 +2279,9 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType) { switch (tree->opval.op) { + case AND_OP: + case OR_OP: + return resultType; case '=': case '?': case ':': @@ -2118,17 +2292,17 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType) case '+': case '-': case LABEL: - return resultType; + return resultType; case '&': - if (!tree->right) - /* can be unary */ - return RESULT_TYPE_NONE; - else - return resultType; + if (!tree->right) + /* can be unary */ + return RESULT_TYPE_NONE; + else + return resultType; case IFX: - return RESULT_TYPE_IFX; + return RESULT_TYPE_IFX; default: - return RESULT_TYPE_NONE; + return RESULT_TYPE_NONE; } } @@ -2142,30 +2316,97 @@ getLeftResultType (ast *tree, RESULT_TYPE resultType) { case '=': case CAST: - if (IS_PTR (LTYPE (tree))) - return RESULT_TYPE_NONE; - else - return getResultTypeFromType (LETYPE (tree)); + if (IS_PTR (LTYPE (tree))) + return RESULT_TYPE_NONE; + else + return getResultTypeFromType (LETYPE (tree)); case RETURN: - if (IS_PTR (currFunc->type->next)) - return RESULT_TYPE_NONE; - else - return getResultTypeFromType (currFunc->type->next); + if (IS_PTR (currFunc->type->next)) + return RESULT_TYPE_NONE; + else + return getResultTypeFromType (currFunc->type->next); case '[': - if (!IS_ARRAY (LTYPE (tree))) - return resultType; - if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256) - return RESULT_TYPE_CHAR; - return resultType; + if (!IS_ARRAY (LTYPE (tree))) + return resultType; + if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255) + return RESULT_TYPE_CHAR; + return resultType; default: - return resultType; + return resultType; + } +} + +/*------------------------------------------------------------------*/ +/* gatherImplicitVariables: assigns correct type information to */ +/* symbols and values created by replaceAstWithTemporary */ +/* and adds the symbols to the declarations list of the */ +/* innermost block that contains them */ +/*------------------------------------------------------------------*/ +void +gatherImplicitVariables (ast * tree, ast * block) +{ + if (!tree) + return; + + if (tree->type == EX_OP && tree->opval.op == BLOCK) + { + /* keep track of containing scope */ + block = tree; + } + if (tree->type == EX_OP && tree->opval.op == '=' && + tree->left->type == EX_VALUE && tree->left->opval.val->sym) + { + symbol *assignee = tree->left->opval.val->sym; + + /* special case for assignment to compiler-generated temporary variable: + compute type of RHS, and set the symbol's type to match */ + if (assignee->type == NULL && assignee->infertype) { + ast *dtr = decorateType (resolveSymbols(tree->right), RESULT_TYPE_NONE); + + if (dtr != tree->right) + tree->right = dtr; + + assignee->type = copyLinkChain(TTYPE(dtr)); + assignee->etype = getSpec(assignee->type); + SPEC_SCLS (assignee->etype) = S_AUTO; + SPEC_OCLS (assignee->etype) = NULL; + SPEC_EXTR (assignee->etype) = 0; + SPEC_STAT (assignee->etype) = 0; + SPEC_VOLATILE (assignee->etype) = 0; + SPEC_ABSA (assignee->etype) = 0; + + wassertl(block != NULL, "implicit variable not contained in block"); + wassert(assignee->next == NULL); + if (block != NULL) { + symbol **decl = &(block->values.sym); + + while (*decl) { + wassert(*decl != assignee); /* should not already be in list */ + decl = &( (*decl)->next ); + } + + *decl = assignee; + } + } + } + if (tree->type == EX_VALUE && !(IS_LITERAL(tree->opval.val->etype)) && + tree->opval.val->type == NULL && + tree->opval.val->sym && + tree->opval.val->sym->infertype) + { + /* fixup type of value for compiler-inferred temporary var */ + tree->opval.val->type = tree->opval.val->sym->type; + tree->opval.val->etype = tree->opval.val->sym->etype; } + + gatherImplicitVariables(tree->left, block); + gatherImplicitVariables(tree->right, block); } /*--------------------------------------------------------------------*/ /* decorateType - compute type for this tree, also does type checking.*/ /* This is done bottom up, since type has to flow upwards. */ -/* resultType flows top-down and forces e.g. char-arithmetik, if the */ +/* resultType flows top-down and forces e.g. char-arithmetic, if the */ /* result is a char and the operand(s) are int's. */ /* It also does constant folding, and parameter checking. */ /*--------------------------------------------------------------------*/ @@ -2215,53 +2456,51 @@ decorateType (ast * tree, RESULT_TYPE resultType) { if (IS_LITERAL (tree->opval.val->etype)) - { + { - /* if this is a character array then declare it */ - if (IS_ARRAY (tree->opval.val->type)) - tree->opval.val = stringToSymbol (tree->opval.val); + /* if this is a character array then declare it */ + if (IS_ARRAY (tree->opval.val->type)) + tree->opval.val = stringToSymbol (tree->opval.val); - /* otherwise just copy the type information */ - COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type); - return tree; - } + /* otherwise just copy the type information */ + COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type); + return tree; + } if (tree->opval.val->sym) - { - /* if the undefined flag is set then give error message */ - if (tree->opval.val->sym->undefined) - { - werror (E_ID_UNDEF, tree->opval.val->sym->name); - /* assume int */ - TTYPE (tree) = TETYPE (tree) = - tree->opval.val->type = tree->opval.val->sym->type = - tree->opval.val->etype = tree->opval.val->sym->etype = - copyLinkChain (INTTYPE); - } - else - { - - /* if impilicit i.e. struct/union member then no type */ - if (tree->opval.val->sym->implicit) - TTYPE (tree) = TETYPE (tree) = NULL; - - else - { - - /* else copy the type */ - COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type); - - /* and mark it as referenced */ - tree->opval.val->sym->isref = 1; - } - } - } - - return tree; - } - - /* if type link for the case of cast */ - if (tree->type == EX_LINK) + { + /* if the undefined flag is set then give error message */ + if (tree->opval.val->sym->undefined) + { + werror (E_ID_UNDEF, tree->opval.val->sym->name); + /* assume int */ + TTYPE (tree) = TETYPE (tree) = + tree->opval.val->type = tree->opval.val->sym->type = + tree->opval.val->etype = tree->opval.val->sym->etype = + copyLinkChain (INTTYPE); + } + else if (tree->opval.val->sym->implicit) + { + /* if implicit i.e. struct/union member then no type */ + TTYPE (tree) = TETYPE (tree) = NULL; + } + else + { + /* copy the type from the value into the ast */ + COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type); + + /* and mark the symbol as referenced */ + tree->opval.val->sym->isref = 1; + } + } + else + wassert(0); /* unreached: all values are literals or symbols */ + + return tree; + } + + /* if type link for the case of cast */ + if (tree->type == EX_LINK) { COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk); return tree; @@ -2274,21 +2513,21 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (tree->opval.op == NULLOP || tree->opval.op == BLOCK) { if (tree->left && tree->left->type == EX_OPERAND - && (tree->left->opval.op == INC_OP - || tree->left->opval.op == DEC_OP) - && tree->left->left) - { - tree->left->right = tree->left->left; - tree->left->left = NULL; - } + && (tree->left->opval.op == INC_OP + || tree->left->opval.op == DEC_OP) + && tree->left->left) + { + tree->left->right = tree->left->left; + tree->left->left = NULL; + } if (tree->right && tree->right->type == EX_OPERAND - && (tree->right->opval.op == INC_OP - || tree->right->opval.op == DEC_OP) - && tree->right->left) - { - tree->right->right = tree->right->left; - tree->right->left = NULL; - } + && (tree->right->opval.op == INC_OP + || tree->right->opval.op == DEC_OP) + && tree->right->left) + { + tree->right->right = tree->right->left; + tree->right->left = NULL; + } } #endif @@ -2306,34 +2545,34 @@ decorateType (ast * tree, RESULT_TYPE resultType) { /* determine which is the array & which the index */ if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && - IS_INTEGRAL (LTYPE (tree))) - { - ast *tempTree = tree->left; - tree->left = tree->right; - tree->right = tempTree; - } + IS_INTEGRAL (LTYPE (tree))) + { + ast *tempTree = tree->left; + tree->left = tree->right; + tree->right = tempTree; + } } /* After decorating the left branch there's type information available in tree->left->?type. If the op is e.g. '=' we extract the type information from there and propagate it to the right branch. */ resultTypeProp = getLeftResultType (tree, resultTypeProp); - + switch (tree->opval.op) { case '?': - /* delay right side for '?' operator since conditional macro - expansions might rely on this */ - dtr = tree->right; - break; - case CALL: - /* decorate right side for CALL (parameter list) in processParms(); - there is resultType available */ - dtr = tree->right; - break; - default: - dtr = decorateType (tree->right, resultTypeProp); - break; + /* delay right side for '?' operator since conditional macro + expansions might rely on this */ + dtr = tree->right; + break; + case CALL: + /* decorate right side for CALL (parameter list) in processParms(); + there is resultType available */ + dtr = tree->right; + break; + default: + dtr = decorateType (tree->right, resultTypeProp); + break; } /* this is to take care of situations @@ -2350,45 +2589,46 @@ decorateType (ast * tree, RESULT_TYPE resultType) switch (tree->opval.op) { - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* array node */ - /*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* array node */ + /*----------------------------*/ case '[': /* first check if this is a array or a pointer */ if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree)))) - { - werror (E_NEED_ARRAY_PTR, "[]"); - goto errorTreeReturn; - } + { + werror (E_NEED_ARRAY_PTR, "[]"); + goto errorTreeReturn; + } /* check if the type of the idx */ if (!IS_INTEGRAL (RTYPE (tree))) - { - werror (E_IDX_NOT_INT); - goto errorTreeReturn; - } + { + werror (E_IDX_NOT_INT); + goto errorTreeReturn; + } /* if the left is an rvalue then error */ if (LRVAL (tree)) - { - werror (E_LVALUE_REQUIRED, "array access"); - goto errorTreeReturn; - } + { + werror (E_LVALUE_REQUIRED, "array access"); + goto errorTreeReturn; + } if (IS_LITERAL (RTYPE (tree))) - { - int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree))); - int arraySize = DCL_ELEM (LTYPE (tree)); - if (arraySize && arrayIndex >= arraySize) - { - werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize); - } - } + { + int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree))); + int arraySize = DCL_ELEM (LTYPE (tree)); + if (arraySize && arrayIndex >= arraySize) + { + werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize); + } + } RRVAL (tree) = 1; COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next); + SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree)); return tree; /*------------------------------------------------------------------*/ @@ -2398,13 +2638,13 @@ decorateType (ast * tree, RESULT_TYPE resultType) case '.': /* if this is not a structure */ if (!IS_STRUCT (LTYPE (tree))) - { - werror (E_STRUCT_UNION, "."); - goto errorTreeReturn; - } + { + werror (E_STRUCT_UNION, "."); + goto errorTreeReturn; + } TTYPE (tree) = structElemType (LTYPE (tree), - (tree->right->type == EX_VALUE ? - tree->right->opval.val : NULL)); + (tree->right->type == EX_VALUE ? + tree->right->opval.val : NULL)); TETYPE (tree) = getSpec (TTYPE (tree)); return tree; @@ -2415,53 +2655,53 @@ decorateType (ast * tree, RESULT_TYPE resultType) case PTR_OP: /* if not pointer to a structure */ if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree))) - { - werror (E_PTR_REQD); - goto errorTreeReturn; - } + { + werror (E_PTR_REQD); + goto errorTreeReturn; + } if (!IS_STRUCT (LTYPE (tree)->next)) - { - werror (E_STRUCT_UNION, "->"); - goto errorTreeReturn; - } + { + werror (E_STRUCT_UNION, "->"); + goto errorTreeReturn; + } TTYPE (tree) = structElemType (LTYPE (tree)->next, - (tree->right->type == EX_VALUE ? - tree->right->opval.val : NULL)); + (tree->right->type == EX_VALUE ? + tree->right->opval.val : NULL)); TETYPE (tree) = getSpec (TTYPE (tree)); /* adjust the storage class */ switch (DCL_TYPE(tree->left->ftype)) { case POINTER: - SPEC_SCLS(TETYPE(tree)) = S_DATA; - break; + SPEC_SCLS(TETYPE(tree)) = S_DATA; + break; case FPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_XDATA; - break; + SPEC_SCLS(TETYPE(tree)) = S_XDATA; + break; case CPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_CODE; - break; + SPEC_SCLS(TETYPE(tree)) = S_CODE; + break; case GPOINTER: - SPEC_SCLS (TETYPE (tree)) = 0; - break; + SPEC_SCLS (TETYPE (tree)) = 0; + break; case PPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_XSTACK; - break; + SPEC_SCLS(TETYPE(tree)) = S_XSTACK; + break; case IPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_IDATA; - break; + SPEC_SCLS(TETYPE(tree)) = S_IDATA; + break; case EEPPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_EEPROM; - break; + SPEC_SCLS(TETYPE(tree)) = S_EEPROM; + break; case UPOINTER: - SPEC_SCLS (TETYPE (tree)) = 0; - break; + SPEC_SCLS (TETYPE (tree)) = 0; + break; case ARRAY: case FUNCTION: - break; + break; } - + /* This breaks with extern declarations, bitfields, and perhaps other */ /* cases (gcse). Let's leave this optimization disabled for now and */ /* ponder if there's a safe way to do this. -- EEP */ @@ -2476,7 +2716,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) */ symbol *sym; symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)), - AST_SYMBOL(tree->right)); + AST_SYMBOL(tree->right)); sym = newSymbol(genSymName (0), 0); sym->type = TTYPE (tree); @@ -2490,7 +2730,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) SPEC_ABSA(sym->etype) = 1; addSym (SymbolTab, sym, sym->name, 0, 0, 0); allocGlobal (sym); - + AST_VALUE (tree) = symbolVal(sym); TLVAL (tree) = 1; TRVAL (tree) = 0; @@ -2499,7 +2739,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->right = NULL; } #endif - + return tree; /*------------------------------------------------------------------*/ @@ -2509,96 +2749,123 @@ decorateType (ast * tree, RESULT_TYPE resultType) case INC_OP: case DEC_OP: { - sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree)); - COPYTYPE (TTYPE (tree), TETYPE (tree), ltc); + sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree)); + COPYTYPE (TTYPE (tree), TETYPE (tree), ltc); if (!tree->initMode && IS_CONSTANT(TTYPE(tree))) - werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--"); + werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--"); - if (tree->right) - RLVAL (tree) = 1; - else - LLVAL (tree) = 1; - return tree; + if (tree->right) + RLVAL (tree) = 1; + else + LLVAL (tree) = 1; + return tree; } /*------------------------------------------------------------------*/ /*----------------------------*/ /* bitwise and */ /*----------------------------*/ - case '&': /* can be unary */ + case '&': /* can be unary */ /* if right is NULL then unary operation */ - if (tree->right) /* not an unary operation */ - { - - if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) - { - werror (E_BITWISE_OP); - werror (W_CONTINUE, "left & right types are "); - printTypeChain (LTYPE (tree), stderr); - fprintf (stderr, ","); - printTypeChain (RTYPE (tree), stderr); - fprintf (stderr, "\n"); - goto errorTreeReturn; - } - - /* if they are both literal */ - if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valBitwise (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree)), '&'); - - tree->right = tree->left = NULL; - TETYPE (tree) = tree->opval.val->etype; - TTYPE (tree) = tree->opval.val->type; - return tree; - } - - /* see if this is a GETHBIT operation if yes - then return that */ - { - ast *otree = optimizeGetHbit (tree); - - if (otree != tree) - return decorateType (otree, RESULT_CHECK); - } - - TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree), - resultType, - tree->opval.op); - TETYPE (tree) = getSpec (TTYPE (tree)); + if (tree->right) /* not an unary operation */ + { + + if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) + { + werror (E_BITWISE_OP); + werror (W_CONTINUE, "left & right types are "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, ","); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } + + /* if they are both literal */ + if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valBitwise (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree)), '&'); + + tree->right = tree->left = NULL; + TETYPE (tree) = tree->opval.val->etype; + TTYPE (tree) = tree->opval.val->type; + return tree; + } + + /* see if this is a GETHBIT operation if yes + then return that */ + { + ast *otree = optimizeGetHbit (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } + + /* see if this is a GETABIT operation if yes + then return that */ + { + ast *otree = optimizeGetAbit (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } + + /* see if this is a GETBYTE operation if yes + then return that */ + { + ast *otree = optimizeGetByte (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } + + /* see if this is a GETWORD operation if yes + then return that */ + { + ast *otree = optimizeGetWord (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } /* if left is a literal exchange left & right */ if (IS_LITERAL (LTYPE (tree))) - { - ast *tTree = tree->left; - tree->left = tree->right; - tree->right = tTree; - } - - /* if right is a literal and */ - /* we can find a 2nd literal in a and-tree then */ - /* rearrange the tree */ - if (IS_LITERAL (RTYPE (tree))) - { - ast *parent; - ast *litTree = searchLitOp (tree, &parent, "&"); - if (litTree) - { - DEBUG_CF("&") - ast *tTree = litTree->left; - litTree->left = tree->right; - tree->right = tTree; - /* both operands in tTree are literal now */ - decorateType (parent, resultType); - } - } - - LRVAL (tree) = RRVAL (tree) = 1; - - return tree; - } + { + ast *tTree = tree->left; + tree->left = tree->right; + tree->right = tTree; + } + + /* if right is a literal and */ + /* we can find a 2nd literal in an and-tree then */ + /* rearrange the tree */ + if (IS_LITERAL (RTYPE (tree))) + { + ast *parent; + ast *litTree = searchLitOp (tree, &parent, "&"); + if (litTree) + { + DEBUG_CF("&") + ast *tTree = litTree->left; + litTree->left = tree->right; + tree->right = tTree; + /* both operands in litTree are literal now */ + decorateType (parent, resultType); + } + } + + LRVAL (tree) = RRVAL (tree) = 1; + + TTYPE (tree) = computeType (LTYPE (tree), + RTYPE (tree), + resultType, + tree->opval.op); + TETYPE (tree) = getSpec (TTYPE (tree)); + + return tree; + } /*------------------------------------------------------------------*/ /*----------------------------*/ @@ -2607,56 +2874,56 @@ decorateType (ast * tree, RESULT_TYPE resultType) p = newLink (DECLARATOR); /* if bit field then error */ if (IS_BITVAR (tree->left->etype)) - { - werror (E_ILLEGAL_ADDR, "address of bit variable"); - goto errorTreeReturn; - } + { + werror (E_ILLEGAL_ADDR, "address of bit variable"); + goto errorTreeReturn; + } if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER) - { - werror (E_ILLEGAL_ADDR, "address of register variable"); - goto errorTreeReturn; - } + { + werror (E_ILLEGAL_ADDR, "address of register variable"); + goto errorTreeReturn; + } if (IS_FUNC (LTYPE (tree))) - { - // this ought to be ignored - return (tree->left); - } + { + // this ought to be ignored + return (tree->left); + } if (IS_LITERAL(LTYPE(tree))) - { - werror (E_ILLEGAL_ADDR, "address of literal"); - goto errorTreeReturn; - } + { + werror (E_ILLEGAL_ADDR, "address of literal"); + goto errorTreeReturn; + } if (LRVAL (tree)) - { - werror (E_LVALUE_REQUIRED, "address of"); - goto errorTreeReturn; - } + { + werror (E_LVALUE_REQUIRED, "address of"); + goto errorTreeReturn; + } if (!LETYPE (tree)) DCL_TYPE (p) = POINTER; else if (SPEC_SCLS (tree->left->etype) == S_CODE) - DCL_TYPE (p) = CPOINTER; + DCL_TYPE (p) = CPOINTER; else if (SPEC_SCLS (tree->left->etype) == S_XDATA) - DCL_TYPE (p) = FPOINTER; + DCL_TYPE (p) = FPOINTER; else if (SPEC_SCLS (tree->left->etype) == S_XSTACK) - DCL_TYPE (p) = PPOINTER; + DCL_TYPE (p) = PPOINTER; else if (SPEC_SCLS (tree->left->etype) == S_IDATA) - DCL_TYPE (p) = IPOINTER; + DCL_TYPE (p) = IPOINTER; else if (SPEC_SCLS (tree->left->etype) == S_EEPROM) - DCL_TYPE (p) = EEPPOINTER; + DCL_TYPE (p) = EEPPOINTER; else if (SPEC_OCLS(tree->left->etype)) - DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype)); + DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype)); else - DCL_TYPE (p) = POINTER; + DCL_TYPE (p) = POINTER; if (IS_AST_SYM_VALUE (tree->left)) - { - AST_SYMBOL (tree->left)->addrtaken = 1; - AST_SYMBOL (tree->left)->allocreq = 1; - } + { + AST_SYMBOL (tree->left)->addrtaken = 1; + AST_SYMBOL (tree->left)->allocreq = 1; + } p->next = LTYPE (tree); TTYPE (tree) = p; @@ -2669,13 +2936,13 @@ decorateType (ast * tree, RESULT_TYPE resultType) && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left)) { symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)), - AST_SYMBOL(tree->left->right)); - AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left), + AST_SYMBOL(tree->left->right)); + AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left), valueFromLit(element->offset)); - tree->left = NULL; - tree->right = NULL; - tree->type = EX_VALUE; - tree->values.literalFromCast = 1; + tree->left = NULL; + tree->right = NULL; + tree->type = EX_VALUE; + tree->values.literalFromCast = 1; } #endif @@ -2686,41 +2953,41 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* bitwise or */ /*----------------------------*/ case '|': - /* if the rewrite succeeds then don't go any furthur */ + /* if the rewrite succeeds then don't go any further */ { - ast *wtree = optimizeRRCRLC (tree); - if (wtree != tree) - return decorateType (wtree, RESULT_CHECK); - - wtree = optimizeSWAP (tree); - if (wtree != tree) - return decorateType (wtree, RESULT_CHECK); + ast *wtree = optimizeRRCRLC (tree); + if (wtree != tree) + return decorateType (wtree, RESULT_TYPE_NONE); + + wtree = optimizeSWAP (tree); + if (wtree != tree) + return decorateType (wtree, RESULT_TYPE_NONE); } /* if left is a literal exchange left & right */ if (IS_LITERAL (LTYPE (tree))) - { - ast *tTree = tree->left; - tree->left = tree->right; - tree->right = tTree; - } + { + ast *tTree = tree->left; + tree->left = tree->right; + tree->right = tTree; + } /* if right is a literal and */ - /* we can find a 2nd literal in a or-tree then */ + /* we can find a 2nd literal in an or-tree then */ /* rearrange the tree */ if (IS_LITERAL (RTYPE (tree))) - { - ast *parent; - ast *litTree = searchLitOp (tree, &parent, "|"); - if (litTree) - { - DEBUG_CF("|") - ast *tTree = litTree->left; - litTree->left = tree->right; - tree->right = tTree; - /* both operands in tTree are literal now */ - decorateType (parent, resultType); - } + { + ast *parent; + ast *litTree = searchLitOp (tree, &parent, "|"); + if (litTree) + { + DEBUG_CF("|") + ast *tTree = litTree->left; + litTree->left = tree->right; + tree->right = tTree; + /* both operands in tTree are literal now */ + decorateType (parent, resultType); + } } /* fall through */ @@ -2730,63 +2997,63 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case '^': if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) - { - werror (E_BITWISE_OP); - werror (W_CONTINUE, "left & right types are "); - printTypeChain (LTYPE (tree), stderr); - fprintf (stderr, ","); - printTypeChain (RTYPE (tree), stderr); - fprintf (stderr, "\n"); - goto errorTreeReturn; - } + { + werror (E_BITWISE_OP); + werror (W_CONTINUE, "left & right types are "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, ","); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } - /* if they are both literal then */ - /* rewrite the tree */ + /* if they are both literal then rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valBitwise (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree)), - tree->opval.op); - tree->right = tree->left = NULL; - TETYPE (tree) = tree->opval.val->etype; - TTYPE (tree) = tree->opval.val->type; - return tree; - } + { + tree->type = EX_VALUE; + tree->opval.val = valBitwise (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree)), + tree->opval.op); + tree->right = tree->left = NULL; + TETYPE (tree) = tree->opval.val->etype; + TTYPE (tree) = tree->opval.val->type; + return tree; + } /* if left is a literal exchange left & right */ if (IS_LITERAL (LTYPE (tree))) - { - ast *tTree = tree->left; - tree->left = tree->right; - tree->right = tTree; - } + { + ast *tTree = tree->left; + tree->left = tree->right; + tree->right = tTree; + } /* if right is a literal and */ /* we can find a 2nd literal in a xor-tree then */ /* rearrange the tree */ if (IS_LITERAL (RTYPE (tree)) && tree->opval.op == '^') /* the same source is used by 'bitwise or' */ - { - ast *parent; - ast *litTree = searchLitOp (tree, &parent, "^"); - if (litTree) - { - DEBUG_CF("^") - ast *tTree = litTree->left; - litTree->left = tree->right; - tree->right = tTree; - /* both operands in litTree are literal now */ - decorateType (parent, resultType); - } + { + ast *parent; + ast *litTree = searchLitOp (tree, &parent, "^"); + if (litTree) + { + DEBUG_CF("^") + ast *tTree = litTree->left; + litTree->left = tree->right; + tree->right = tTree; + /* both operands in litTree are literal now */ + decorateType (parent, resultType); + } } LRVAL (tree) = RRVAL (tree) = 1; - TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree), - resultType, - tree->opval.op)); + + TTYPE (tree) = computeType (LTYPE (tree), + RTYPE (tree), + resultType, + tree->opval.op); + TETYPE (tree) = getSpec (TTYPE (tree)); return tree; @@ -2796,64 +3063,64 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case '/': if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree))) - { - werror (E_INVALID_OP, "divide"); - goto errorTreeReturn; - } + { + werror (E_INVALID_OP, "divide"); + goto errorTreeReturn; + } /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valDiv (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree))); - tree->right = tree->left = NULL; - TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); - return tree; - } + { + tree->type = EX_VALUE; + tree->opval.val = valDiv (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree), - resultType, - tree->opval.op)); + computeType (LTYPE (tree), + RTYPE (tree), + resultType, + tree->opval.op)); /* if right is a literal and */ /* left is also a division by a literal then */ /* rearrange the tree */ if (IS_LITERAL (RTYPE (tree)) /* avoid infinite loop */ - && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1) - { - ast *parent; - ast *litTree = searchLitOp (tree, &parent, "/"); - if (litTree) - { - if (IS_LITERAL (RTYPE (litTree))) - { - /* foo_div */ - DEBUG_CF("div r") - litTree->right = newNode ('*', - litTree->right, - copyAst (tree->right)); - litTree->right->lineno = tree->lineno; - - tree->right->opval.val = constVal ("1"); - decorateType (parent, resultType); - } - else - { - /* litTree->left is literal: no gcse possible. - We can't call decorateType(parent, RESULT_CHECK), because - this would cause an infinit loop. */ - parent->decorated = 1; - decorateType (litTree, resultType); - } - } - } + && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 1) + { + ast *parent; + ast *litTree = searchLitOp (tree, &parent, "/"); + if (litTree) + { + if (IS_LITERAL (RTYPE (litTree))) + { + /* foo_div */ + DEBUG_CF("div r") + litTree->right = newNode ('*', + litTree->right, + copyAst (tree->right)); + litTree->right->lineno = tree->lineno; + + tree->right->opval.val = constVal ("1"); + decorateType (parent, resultType); + } + else + { + /* litTree->left is literal: no gcse possible. + We can't call decorateType(parent, RESULT_TYPE_NONE), because + this would cause an infinit loop. */ + parent->decorated = 1; + decorateType (litTree, resultType); + } + } + } return tree; @@ -2863,150 +3130,150 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case '%': if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) - { - werror (E_BITWISE_OP); - werror (W_CONTINUE, "left & right types are "); - printTypeChain (LTYPE (tree), stderr); - fprintf (stderr, ","); - printTypeChain (RTYPE (tree), stderr); - fprintf (stderr, "\n"); - goto errorTreeReturn; - } + { + werror (E_BITWISE_OP); + werror (W_CONTINUE, "left & right types are "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, ","); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valMod (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree))); - tree->right = tree->left = NULL; - TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); - return tree; - } + { + tree->type = EX_VALUE; + tree->opval.val = valMod (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree), - resultType, - tree->opval.op)); + computeType (LTYPE (tree), + RTYPE (tree), + resultType, + tree->opval.op)); return tree; /*------------------------------------------------------------------*/ /*----------------------------*/ /* address dereference */ /*----------------------------*/ - case '*': /* can be unary : if right is null then unary operation */ + case '*': /* can be unary : if right is null then unary operation */ if (!tree->right) - { - if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree))) - { - werror (E_PTR_REQD); - goto errorTreeReturn; - } - - if (LRVAL (tree)) - { - werror (E_LVALUE_REQUIRED, "pointer deref"); - goto errorTreeReturn; - } - if (IS_ADDRESS_OF_OP(tree->left)) + { + if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree))) + { + werror (E_PTR_REQD); + goto errorTreeReturn; + } + + if (LRVAL (tree)) + { + werror (E_LVALUE_REQUIRED, "pointer deref"); + goto errorTreeReturn; + } + if (IS_ADDRESS_OF_OP(tree->left)) { /* replace *&obj with obj */ return tree->left->left; } TTYPE (tree) = copyLinkChain (LTYPE (tree)->next); - TETYPE (tree) = getSpec (TTYPE (tree)); - /* adjust the storage class */ - switch (DCL_TYPE(tree->left->ftype)) { - case POINTER: - SPEC_SCLS(TETYPE(tree)) = S_DATA; - break; - case FPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_XDATA; - break; - case CPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_CODE; - break; - case GPOINTER: - SPEC_SCLS (TETYPE (tree)) = 0; - break; - case PPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_XSTACK; - break; - case IPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_IDATA; - break; - case EEPPOINTER: - SPEC_SCLS(TETYPE(tree)) = S_EEPROM; - break; - case UPOINTER: - SPEC_SCLS (TETYPE (tree)) = 0; + TETYPE (tree) = getSpec (TTYPE (tree)); + /* adjust the storage class */ + switch (DCL_TYPE(tree->left->ftype)) { + case POINTER: + SPEC_SCLS(TETYPE(tree)) = S_DATA; + break; + case FPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_XDATA; + break; + case CPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_CODE; + break; + case GPOINTER: + SPEC_SCLS (TETYPE (tree)) = 0; + break; + case PPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_XSTACK; + break; + case IPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_IDATA; + break; + case EEPPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_EEPROM; break; - case ARRAY: - case FUNCTION: - break; - } - return tree; - } + case UPOINTER: + SPEC_SCLS (TETYPE (tree)) = 0; + break; + case ARRAY: + case FUNCTION: + break; + } + return tree; + } /*------------------------------------------------------------------*/ /*----------------------------*/ /* multiplication */ /*----------------------------*/ if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree))) - { - werror (E_INVALID_OP, "multiplication"); - goto errorTreeReturn; - } + { + werror (E_INVALID_OP, "multiplication"); + goto errorTreeReturn; + } /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valMult (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree))); - tree->right = tree->left = NULL; - TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); - return tree; - } + { + tree->type = EX_VALUE; + tree->opval.val = valMult (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } /* if left is a literal exchange left & right */ if (IS_LITERAL (LTYPE (tree))) - { - ast *tTree = tree->left; - tree->left = tree->right; - tree->right = tTree; - } + { + ast *tTree = tree->left; + tree->left = tree->right; + tree->right = tTree; + } /* if right is a literal and */ /* we can find a 2nd literal in a mul-tree then */ /* rearrange the tree */ if (IS_LITERAL (RTYPE (tree))) - { - ast *parent; - ast *litTree = searchLitOp (tree, &parent, "*"); - if (litTree) - { - DEBUG_CF("mul") - ast *tTree = litTree->left; - litTree->left = tree->right; - tree->right = tTree; - /* both operands in litTree are literal now */ - decorateType (parent, resultType); - } + { + ast *parent; + ast *litTree = searchLitOp (tree, &parent, "*"); + if (litTree) + { + DEBUG_CF("mul") + ast *tTree = litTree->left; + litTree->left = tree->right; + tree->right = tTree; + /* both operands in litTree are literal now */ + decorateType (parent, resultType); + } } LRVAL (tree) = RRVAL (tree) = 1; tree->left = addCast (tree->left, resultType, FALSE); tree->right = addCast (tree->right, resultType, FALSE); TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree), - resultType, - tree->opval.op)); + computeType (LTYPE (tree), + RTYPE (tree), + resultType, + tree->opval.op)); return tree; @@ -3017,26 +3284,26 @@ decorateType (ast * tree, RESULT_TYPE resultType) case '+': /* if unary plus */ if (!tree->right) - { - if (!IS_ARITHMETIC (LTYPE (tree))) - { - werror (E_UNARY_OP, '+'); - goto errorTreeReturn; - } - - /* if left is a literal then do it */ - if (IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valFromType (LETYPE (tree)); - tree->left = NULL; - TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - return tree; - } - LRVAL (tree) = 1; - COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); - return tree; - } + { + if (!IS_ARITHMETIC (LTYPE (tree))) + { + werror (E_UNARY_OP, '+'); + goto errorTreeReturn; + } + + /* if left is a literal then do it */ + if (IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valFromType (LETYPE (tree)); + tree->left = NULL; + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } + LRVAL (tree) = 1; + COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); + return tree; + } /*------------------------------------------------------------------*/ /*----------------------------*/ @@ -3046,141 +3313,145 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* this is not a unary operation */ /* if both pointers then problem */ if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) && - (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)))) - { - werror (E_PTR_PLUS_PTR); - goto errorTreeReturn; - } + (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)))) + { + werror (E_PTR_PLUS_PTR); + goto errorTreeReturn; + } if (!IS_ARITHMETIC (LTYPE (tree)) && - !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree))) - { - werror (E_PLUS_INVALID, "+"); - goto errorTreeReturn; - } + !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree))) + { + werror (E_PLUS_INVALID, "+"); + goto errorTreeReturn; + } if (!IS_ARITHMETIC (RTYPE (tree)) && - !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree))) - { - werror (E_PLUS_INVALID, "+"); - goto errorTreeReturn; - } + !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree))) + { + werror (E_PLUS_INVALID, "+"); + goto errorTreeReturn; + } /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->left = addCast (tree->left, resultType, TRUE); + { + tree->type = EX_VALUE; + tree->left = addCast (tree->left, resultType, TRUE); tree->right = addCast (tree->right, resultType, TRUE); - tree->opval.val = valPlus (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree))); - tree->right = tree->left = NULL; - TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); - return tree; - } + tree->opval.val = valPlus (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } /* if the right is a pointer or left is a literal xchange left & right */ if (IS_ARRAY (RTYPE (tree)) || - IS_PTR (RTYPE (tree)) || - IS_LITERAL (LTYPE (tree))) - { - ast *tTree = tree->left; - tree->left = tree->right; - tree->right = tTree; - } + IS_PTR (RTYPE (tree)) || + IS_LITERAL (LTYPE (tree))) + { + ast *tTree = tree->left; + tree->left = tree->right; + tree->right = tTree; + } /* if right is a literal and */ /* left is also an addition/subtraction with a literal then */ /* rearrange the tree */ if (IS_LITERAL (RTYPE (tree))) - { - ast *litTree, *parent; - litTree = searchLitOp (tree, &parent, "+-"); - if (litTree) - { - if (litTree->opval.op == '+') - { - /* foo_aa */ - DEBUG_CF("+ 1 AA") - ast *tTree = litTree->left; - litTree->left = tree->right; - tree->right = tree->left; - tree->left = tTree; - } - else if (litTree->opval.op == '-') - { - if (IS_LITERAL (RTYPE (litTree))) - { - DEBUG_CF("+ 2 ASR") - /* foo_asr */ - ast *tTree = litTree->left; - litTree->left = tree->right; - tree->right = tTree; - } - else - { - DEBUG_CF("+ 3 ASL") - /* foo_asl */ - ast *tTree = litTree->right; - litTree->right = tree->right; - tree->right = tTree; - litTree->opval.op = '+'; - tree->opval.op = '-'; - } - } - decorateType (parent, resultType); - } - } + { + ast *litTree, *parent; + litTree = searchLitOp (tree, &parent, "+-"); + if (litTree) + { + if (litTree->opval.op == '+') + { + /* foo_aa */ + DEBUG_CF("+ 1 AA") + ast *tTree = litTree->left; + litTree->left = tree->right; + tree->right = tree->left; + tree->left = tTree; + } + else if (litTree->opval.op == '-') + { + if (IS_LITERAL (RTYPE (litTree))) + { + DEBUG_CF("+ 2 ASR") + /* foo_asr */ + ast *tTree = litTree->left; + litTree->left = tree->right; + tree->right = tTree; + } + else + { + DEBUG_CF("+ 3 ASL") + /* foo_asl */ + ast *tTree = litTree->right; + litTree->right = tree->right; + tree->right = tTree; + litTree->opval.op = '+'; + tree->opval.op = '-'; + } + } + decorateType (parent, resultType); + } + } LRVAL (tree) = RRVAL (tree) = 1; /* if the left is a pointer */ if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) ) - TETYPE (tree) = getSpec (TTYPE (tree) = - LTYPE (tree)); + TETYPE (tree) = getSpec (TTYPE (tree) = + LTYPE (tree)); else - { - tree->left = addCast (tree->left, resultType, TRUE); + { + tree->left = addCast (tree->left, resultType, TRUE); tree->right = addCast (tree->right, resultType, TRUE); TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree), - resultType, - tree->opval.op)); - } - + computeType (LTYPE (tree), + RTYPE (tree), + resultType, + tree->opval.op)); + } + return tree; /*------------------------------------------------------------------*/ /*----------------------------*/ /* unary '-' */ /*----------------------------*/ - case '-': /* can be unary */ + case '-': /* can be unary */ /* if right is null then unary */ if (!tree->right) - { - - if (!IS_ARITHMETIC (LTYPE (tree))) - { - werror (E_UNARY_OP, tree->opval.op); - goto errorTreeReturn; - } - - /* if left is a literal then do it */ - if (IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valUnaryPM (valFromType (LETYPE (tree))); - tree->left = NULL; - TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - SPEC_USIGN(TETYPE(tree)) = 0; - return tree; - } - LRVAL (tree) = 1; - TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree)); - return tree; - } + { + + if (!IS_ARITHMETIC (LTYPE (tree))) + { + werror (E_UNARY_OP, tree->opval.op); + goto errorTreeReturn; + } + + /* if left is a literal then do it */ + if (IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valUnaryPM (valFromType (LETYPE (tree))); + tree->left = NULL; + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } + tree->left = addCast (tree->left, resultType, TRUE); + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + NULL, + resultType, + tree->opval.op)); + LRVAL (tree) = 1; + return tree; + } /*------------------------------------------------------------------*/ /*----------------------------*/ @@ -3188,76 +3459,76 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ if (!(IS_PTR (LTYPE (tree)) || - IS_ARRAY (LTYPE (tree)) || - IS_ARITHMETIC (LTYPE (tree)))) - { - werror (E_PLUS_INVALID, "-"); - goto errorTreeReturn; - } + IS_ARRAY (LTYPE (tree)) || + IS_ARITHMETIC (LTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-"); + goto errorTreeReturn; + } if (!(IS_PTR (RTYPE (tree)) || - IS_ARRAY (RTYPE (tree)) || - IS_ARITHMETIC (RTYPE (tree)))) - { - werror (E_PLUS_INVALID, "-"); - goto errorTreeReturn; - } + IS_ARRAY (RTYPE (tree)) || + IS_ARITHMETIC (RTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-"); + goto errorTreeReturn; + } if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) && - !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) || - IS_INTEGRAL (RTYPE (tree)))) - { - werror (E_PLUS_INVALID, "-"); - goto errorTreeReturn; - } + !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) || + IS_INTEGRAL (RTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-"); + goto errorTreeReturn; + } /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->left = addCast (tree->left, resultType, TRUE); - tree->right = addCast (tree->right, resultType, TRUE); - tree->opval.val = valMinus (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree))); - tree->right = tree->left = NULL; - TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); - return tree; - } + { + tree->type = EX_VALUE; + tree->left = addCast (tree->left, resultType, TRUE); + tree->right = addCast (tree->right, resultType, TRUE); + tree->opval.val = valMinus (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } /* if the left & right are equal then zero */ if (isAstEqual (tree->left, tree->right)) - { - tree->type = EX_VALUE; - tree->left = tree->right = NULL; - tree->opval.val = constVal ("0"); - TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - return tree; - } + { + tree->type = EX_VALUE; + tree->left = tree->right = NULL; + tree->opval.val = constVal ("0"); + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } /* if both of them are pointers or arrays then */ /* the result is going to be an integer */ if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) && - (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree)))) - TETYPE (tree) = TTYPE (tree) = newIntLink (); + (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree)))) + TETYPE (tree) = TTYPE (tree) = newIntLink (); else - /* if only the left is a pointer */ - /* then result is a pointer */ + /* if only the left is a pointer */ + /* then result is a pointer */ if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) - TETYPE (tree) = getSpec (TTYPE (tree) = - LTYPE (tree)); + TETYPE (tree) = getSpec (TTYPE (tree) = + LTYPE (tree)); else - { - tree->left = addCast (tree->left, resultType, TRUE); - tree->right = addCast (tree->right, resultType, TRUE); + { + tree->left = addCast (tree->left, resultType, TRUE); + tree->right = addCast (tree->right, resultType, TRUE); - TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree), - resultType, - tree->opval.op)); - } + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree), + resultType, + tree->opval.op)); + } LRVAL (tree) = RRVAL (tree) = 1; @@ -3266,50 +3537,50 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* rearrange the tree */ if (IS_LITERAL (RTYPE (tree)) /* avoid infinite loop */ - && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0) - { - ast *litTree, *litParent; - litTree = searchLitOp (tree, &litParent, "+-"); - if (litTree) - { - if (litTree->opval.op == '+') - { - /* foo_sa */ - DEBUG_CF("- 1 SA") - ast *tTree = litTree->left; - litTree->left = litTree->right; - litTree->right = tree->right; - tree->right = tTree; - tree->opval.op = '+'; - litTree->opval.op = '-'; - } - else if (litTree->opval.op == '-') - { - if (IS_LITERAL (RTYPE (litTree))) - { - /* foo_ssr */ - DEBUG_CF("- 2 SSR") - ast *tTree = litTree->left; - litTree->left = tree->right; - tree->right = litParent->left; - litParent->left = tTree; - litTree->opval.op = '+'; - - tree->decorated = 0; - decorateType (tree, resultType); - } - else - { - /* foo_ssl */ - DEBUG_CF("- 3 SSL") - ast *tTree = litTree->right; - litTree->right = tree->right; - tree->right = tTree; - } - } - decorateType (litParent, resultType); - } - } + && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 0) + { + ast *litTree, *litParent; + litTree = searchLitOp (tree, &litParent, "+-"); + if (litTree) + { + if (litTree->opval.op == '+') + { + /* foo_sa */ + DEBUG_CF("- 1 SA") + ast *tTree = litTree->left; + litTree->left = litTree->right; + litTree->right = tree->right; + tree->right = tTree; + tree->opval.op = '+'; + litTree->opval.op = '-'; + } + else if (litTree->opval.op == '-') + { + if (IS_LITERAL (RTYPE (litTree))) + { + /* foo_ssr */ + DEBUG_CF("- 2 SSR") + ast *tTree = litTree->left; + litTree->left = tree->right; + tree->right = litParent->left; + litParent->left = tTree; + litTree->opval.op = '+'; + + tree->decorated = 0; + decorateType (tree, resultType); + } + else + { + /* foo_ssl */ + DEBUG_CF("- 3 SSL") + ast *tTree = litTree->right; + litTree->right = tree->right; + tree->right = tTree; + } + } + decorateType (litParent, resultType); + } + } return tree; /*------------------------------------------------------------------*/ @@ -3319,10 +3590,10 @@ decorateType (ast * tree, RESULT_TYPE resultType) case '~': /* can be only integral type */ if (!IS_INTEGRAL (LTYPE (tree))) - { - werror (E_UNARY_OP, tree->opval.op); - goto errorTreeReturn; - } + { + werror (E_UNARY_OP, tree->opval.op); + goto errorTreeReturn; + } /* if left is a literal then do it */ if (IS_LITERAL (LTYPE (tree))) @@ -3333,7 +3604,23 @@ decorateType (ast * tree, RESULT_TYPE resultType) TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; return addCast (tree, resultType, TRUE); } - tree->left = addCast (tree->left, resultType, TRUE); + + if (resultType == RESULT_TYPE_BIT && + IS_UNSIGNED (tree->left->etype) && + getSize (tree->left->etype) < INTSIZE) + { + /* promotion rules are responsible for this strange result: + bit -> int -> ~int -> bit + uchar -> int -> ~int -> bit + */ + werror(W_COMPLEMENT); + + /* optimize bit-result, even if we optimize a buggy source */ + tree->type = EX_VALUE; + tree->opval.val = constVal ("1"); + } + else + tree->left = addCast (tree->left, resultType, TRUE); LRVAL (tree) = 1; COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); return tree; @@ -3345,24 +3632,38 @@ decorateType (ast * tree, RESULT_TYPE resultType) case '!': /* can be pointer */ if (!IS_ARITHMETIC (LTYPE (tree)) && - !IS_PTR (LTYPE (tree)) && - !IS_ARRAY (LTYPE (tree))) - { - werror (E_UNARY_OP, tree->opval.op); - goto errorTreeReturn; - } + !IS_PTR (LTYPE (tree)) && + !IS_ARRAY (LTYPE (tree))) + { + werror (E_UNARY_OP, tree->opval.op); + goto errorTreeReturn; + } + + /* if left is another '!' */ + if (tree->left->opval.op == '!') + { + /* remove double '!!X' by 'X ? 1 : 0' */ + tree->opval.op = '?'; + tree->left = tree->left->left; + tree->right = newNode (':', + newAst_VALUE (constVal ("1")), + newAst_VALUE (constVal ("0"))); + tree->right->lineno = tree->lineno; + tree->decorated = 0; + return decorateType (tree, resultType); + } /* if left is a literal then do it */ if (IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valNot (valFromType (LETYPE (tree))); - tree->left = NULL; - TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - return tree; - } + { + tree->type = EX_VALUE; + tree->opval.val = valNot (valFromType (LETYPE (tree))); + tree->left = NULL; + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } LRVAL (tree) = 1; - TTYPE (tree) = TETYPE (tree) = newCharLink (); + TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); return tree; /*------------------------------------------------------------------*/ @@ -3377,76 +3678,103 @@ decorateType (ast * tree, RESULT_TYPE resultType) return tree; case GETHBIT: - TTYPE (tree) = TETYPE (tree) = newCharLink (); + case GETABIT: + TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); + return tree; + + case GETBYTE: + TTYPE (tree) = TETYPE (tree) = newCharLink(); + return tree; + + case GETWORD: + TTYPE (tree) = TETYPE (tree) = newIntLink(); return tree; case LEFT_OP: case RIGHT_OP: if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype)) - { - werror (E_SHIFT_OP_INVALID); - werror (W_CONTINUE, "left & right types are "); - printTypeChain (LTYPE (tree), stderr); - fprintf (stderr, ","); - printTypeChain (RTYPE (tree), stderr); - fprintf (stderr, "\n"); - goto errorTreeReturn; - } + { + werror (E_SHIFT_OP_INVALID); + werror (W_CONTINUE, "left & right types are "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, ","); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } /* make smaller type only if it's a LEFT_OP */ if (tree->opval.op == LEFT_OP) tree->left = addCast (tree->left, resultType, TRUE); - + /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valShift (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree)), - (tree->opval.op == LEFT_OP ? 1 : 0)); - tree->right = tree->left = NULL; - TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); - return tree; - } + { + tree->type = EX_VALUE; + tree->opval.val = valShift (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree)), + (tree->opval.op == LEFT_OP ? 1 : 0)); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + + /* see if this is a GETBYTE operation if yes + then return that */ + { + ast *otree = optimizeGetByte (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } + + /* see if this is a GETWORD operation if yes + then return that */ + { + ast *otree = optimizeGetWord (tree, resultType); + + if (otree != tree) + return decorateType (otree, RESULT_TYPE_NONE); + } LRVAL (tree) = RRVAL (tree) = 1; if (tree->opval.op == LEFT_OP) - { - TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - NULL, - resultType, - tree->opval.op)); - } + { + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + NULL, + resultType, + tree->opval.op)); + } else /* RIGHT_OP */ - { - /* no promotion necessary */ - TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree)); - if (IS_LITERAL (TTYPE (tree))) - SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL; - } + { + /* no promotion necessary */ + TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree)); + if (IS_LITERAL (TTYPE (tree))) + SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL; + } /* if only the right side is a literal & we are shifting more than size of the left operand then zero */ if (IS_LITERAL (RTYPE (tree)) && - ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >= - (getSize (TETYPE (tree)) * 8)) - { - if (tree->opval.op==LEFT_OP || - (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) - { - lineno=tree->lineno; - werror (W_SHIFT_CHANGED, - (tree->opval.op == LEFT_OP ? "left" : "right")); - tree->type = EX_VALUE; - tree->left = tree->right = NULL; - tree->opval.val = constVal ("0"); - TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - return tree; - } - } + ((TYPE_TARGET_ULONG) floatFromVal (valFromType (RETYPE (tree)))) >= + (getSize (TETYPE (tree)) * 8)) + { + if (tree->opval.op==LEFT_OP || + (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) + { + lineno=tree->lineno; + werror (W_SHIFT_CHANGED, + (tree->opval.op == LEFT_OP ? "left" : "right")); + tree->type = EX_VALUE; + tree->left = tree->right = NULL; + tree->opval.val = constVal ("0"); + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } + } return tree; @@ -3454,87 +3782,125 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ /* casting */ /*----------------------------*/ - case CAST: /* change the type */ + case CAST: /* change the type */ /* cannot cast to an aggregate type */ if (IS_AGGREGATE (LTYPE (tree))) - { - werror (E_CAST_ILLEGAL); - goto errorTreeReturn; - } + { + werror (E_CAST_ILLEGAL); + goto errorTreeReturn; + } /* make sure the type is complete and sane */ + changePointer(LTYPE(tree)); checkTypeSanity(LETYPE(tree), "(cast)"); + /* if 'from' and 'to' are the same remove the superfluous cast, */ + /* this helps other optimizations */ + if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1) + { + return tree->right; + } + /* If code memory is read only, then pointers to code memory */ /* implicitly point to constants -- make this explicit */ { - sym_link *t = LTYPE(tree); - while (t && t->next) - { - if (IS_CODEPTR(t) && port->mem.code_ro) - { - if (IS_SPEC(t->next)) - SPEC_CONST (t->next) = 1; - else - DCL_PTR_CONST (t->next) = 1; - } - t = t->next; + sym_link *t = LTYPE(tree); + while (t && t->next) + { + if (IS_CODEPTR(t) && port->mem.code_ro) + { + if (IS_SPEC(t->next)) + SPEC_CONST (t->next) = 1; + else + DCL_PTR_CONST (t->next) = 1; + } + t = t->next; } } #if 0 /* if the right is a literal replace the tree */ if (IS_LITERAL (RETYPE (tree))) { - if (!IS_PTR (LTYPE (tree))) { - tree->type = EX_VALUE; - tree->opval.val = - valCastLiteral (LTYPE (tree), - floatFromVal (valFromType (RETYPE (tree)))); - tree->left = NULL; - tree->right = NULL; - TTYPE (tree) = tree->opval.val->type; - tree->values.literalFromCast = 1; - } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && - ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ { - sym_link *rest = LTYPE(tree)->next; - werror(W_LITERAL_GENERIC); - TTYPE(tree) = newLink(DECLARATOR); - DCL_TYPE(TTYPE(tree)) = FPOINTER; - TTYPE(tree)->next = rest; - tree->left->opval.lnk = TTYPE(tree); - LRVAL (tree) = 1; - } else { - TTYPE (tree) = LTYPE (tree); - LRVAL (tree) = 1; - } + if (!IS_PTR (LTYPE (tree))) { + tree->type = EX_VALUE; + tree->opval.val = + valCastLiteral (LTYPE (tree), + floatFromVal (valFromType (RETYPE (tree)))); + tree->left = NULL; + tree->right = NULL; + TTYPE (tree) = tree->opval.val->type; + tree->values.literalFromCast = 1; + } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && + ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ { + sym_link *rest = LTYPE(tree)->next; + werror(W_LITERAL_GENERIC); + TTYPE(tree) = newLink(DECLARATOR); + DCL_TYPE(TTYPE(tree)) = FPOINTER; + TTYPE(tree)->next = rest; + tree->left->opval.lnk = TTYPE(tree); + LRVAL (tree) = 1; + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } } else { - TTYPE (tree) = LTYPE (tree); - LRVAL (tree) = 1; + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; } #else #if 0 // this is already checked, now this could be explicit /* if pointer to struct then check names */ if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) && - IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) && - strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) - { - werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag, - SPEC_STRUCT(LETYPE(tree))->tag); - } + IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) && + strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) + { + werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag, + SPEC_STRUCT(LETYPE(tree))->tag); + } #endif if (IS_ADDRESS_OF_OP(tree->right) && IS_AST_SYM_VALUE (tree->right->left) && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) { + symbol * sym = AST_SYMBOL (tree->right->left); + unsigned int gptype = 0; + unsigned int addr = SPEC_ADDR (sym->etype); + + if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE) + || TARGET_IS_PIC16) ) + { + switch (SPEC_SCLS (sym->etype)) + { + case S_CODE: + gptype = GPTYPE_CODE; + break; + case S_XDATA: + gptype = GPTYPE_FAR; + break; + case S_DATA: + case S_IDATA: + gptype = GPTYPE_NEAR; + break; + case S_PDATA: + gptype = GPTYPE_XSTACK; + break; + default: + gptype = 0; + + if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED)) + gptype = GPTYPE_NEAR; + } + addr |= gptype << (8*(GPTRSIZE - 1)); + } + tree->type = EX_VALUE; - tree->opval.val = - valCastLiteral (LTYPE (tree), - SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype)); - TTYPE (tree) = tree->opval.val->type; + tree->opval.val = + valCastLiteral (LTYPE (tree), addr); + TTYPE (tree) = tree->opval.val->type; TETYPE (tree) = getSpec (TTYPE (tree)); - tree->left = NULL; - tree->right = NULL; - tree->values.literalFromCast = 1; + tree->left = NULL; + tree->right = NULL; + tree->values.literalFromCast = 1; return tree; } @@ -3550,21 +3916,21 @@ decorateType (ast * tree, RESULT_TYPE resultType) symbol *element = getStructElement ( SPEC_STRUCT (LETYPE(tree->right->left)), - AST_SYMBOL(tree->right->left->right) + AST_SYMBOL(tree->right->left->right) ); if (element) { tree->type = EX_VALUE; - tree->opval.val = valCastLiteral ( - LTYPE (tree), - element->offset + tree->opval.val = valCastLiteral ( + LTYPE (tree), + element->offset + floatFromVal (valFromType (RTYPE (tree->right->left->left))) ); - TTYPE (tree) = tree->opval.val->type; + TTYPE (tree) = tree->opval.val->type; TETYPE (tree) = getSpec (TTYPE (tree)); - tree->left = NULL; - tree->right = NULL; + tree->left = NULL; + tree->right = NULL; return tree; } } @@ -3572,7 +3938,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* if the right is a literal replace the tree */ if (IS_LITERAL (RETYPE (tree))) { #if 0 - if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) { + if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) { /* rewrite (type *)litaddr as &temp and define type at litaddr temp @@ -3604,22 +3970,22 @@ decorateType (ast * tree, RESULT_TYPE resultType) newTree->left->lineno = tree->lineno; LTYPE (newTree) = sym->type; LETYPE (newTree) = sym->etype; - LLVAL (newTree) = 1; + LLVAL (newTree) = 1; LRVAL (newTree) = 0; TLVAL (newTree) = 1; return newTree; } - #endif + #endif if (!IS_PTR (LTYPE (tree))) { - tree->type = EX_VALUE; - tree->opval.val = - valCastLiteral (LTYPE (tree), - floatFromVal (valFromType (RTYPE (tree)))); - TTYPE (tree) = tree->opval.val->type; - tree->left = NULL; - tree->right = NULL; - tree->values.literalFromCast = 1; - TETYPE (tree) = getSpec (TTYPE (tree)); + tree->type = EX_VALUE; + tree->opval.val = + valCastLiteral (LTYPE (tree), + floatFromVal (valFromType (RTYPE (tree)))); + TTYPE (tree) = tree->opval.val->type; + tree->left = NULL; + tree->right = NULL; + tree->values.literalFromCast = 1; + TETYPE (tree) = getSpec (TTYPE (tree)); return tree; } } @@ -3639,36 +4005,36 @@ decorateType (ast * tree, RESULT_TYPE resultType) case OR_OP: /* each must be arithmetic type or be a pointer */ if (!IS_PTR (LTYPE (tree)) && - !IS_ARRAY (LTYPE (tree)) && - !IS_INTEGRAL (LTYPE (tree))) - { - werror (E_COMPARE_OP); - goto errorTreeReturn; - } + !IS_ARRAY (LTYPE (tree)) && + !IS_INTEGRAL (LTYPE (tree))) + { + werror (E_COMPARE_OP); + goto errorTreeReturn; + } if (!IS_PTR (RTYPE (tree)) && - !IS_ARRAY (RTYPE (tree)) && - !IS_INTEGRAL (RTYPE (tree))) - { - werror (E_COMPARE_OP); - goto errorTreeReturn; - } + !IS_ARRAY (RTYPE (tree)) && + !IS_INTEGRAL (RTYPE (tree))) + { + werror (E_COMPARE_OP); + goto errorTreeReturn; + } /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && - IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)), - valFromType (RTYPE (tree)), - tree->opval.op); - tree->right = tree->left = NULL; - TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); - return tree; - } + IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)), + valFromType (RTYPE (tree)), + tree->opval.op); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } LRVAL (tree) = RRVAL (tree) = 1; - TTYPE (tree) = TETYPE (tree) = newCharLink (); + TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); return tree; /*------------------------------------------------------------------*/ @@ -3682,115 +4048,226 @@ decorateType (ast * tree, RESULT_TYPE resultType) case EQ_OP: case NE_OP: { - ast *lt = optimizeCompare (tree); + ast *lt = optimizeCompare (tree); - if (tree != lt) - return lt; + if (tree != lt) + return lt; } /* if they are pointers they must be castable */ if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree))) - { - if (tree->opval.op==EQ_OP && - !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) { - // we cannot cast a gptr to a !gptr: switch the leaves - struct ast *s=tree->left; - tree->left=tree->right; - tree->right=s; - } - if (compareType (LTYPE (tree), RTYPE (tree)) == 0) - { - werror (E_COMPARE_OP); - fprintf (stderr, "comparing type "); - printTypeChain (LTYPE (tree), stderr); - fprintf (stderr, "to type "); - printTypeChain (RTYPE (tree), stderr); - fprintf (stderr, "\n"); - goto errorTreeReturn; - } - } + { + if (tree->opval.op==EQ_OP && + !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) { + // we cannot cast a gptr to a !gptr: switch the leaves + struct ast *s=tree->left; + tree->left=tree->right; + tree->right=s; + } + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) + { + werror (E_COMPARE_OP); + fprintf (stderr, "comparing type "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, "to type "); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } + } /* else they should be promotable to one another */ else - { - if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) || - (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))))) - - if (compareType (LTYPE (tree), RTYPE (tree)) == 0) - { - werror (E_COMPARE_OP); - fprintf (stderr, "comparing type "); - printTypeChain (LTYPE (tree), stderr); - fprintf (stderr, "to type "); - printTypeChain (RTYPE (tree), stderr); - fprintf (stderr, "\n"); - goto errorTreeReturn; - } - } - /* if unsigned value < 0 then always false */ + { + if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) || + (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))))) + + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) + { + werror (E_COMPARE_OP); + fprintf (stderr, "comparing type "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, "to type "); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } + } + + { + CCR_RESULT ccr_result = CCR_OK; + + /* if left is integral and right is literal + then check constant range */ + if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) + ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree), + tree->opval.op, FALSE); + if (ccr_result == CCR_OK && + IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) + ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree), + tree->opval.op, TRUE); + switch (ccr_result) + { + case CCR_ALWAYS_TRUE: + case CCR_ALWAYS_FALSE: + if (!options.lessPedantic) + werror (W_COMP_RANGE, + ccr_result == CCR_ALWAYS_TRUE ? "true" : "false"); + return decorateType (newAst_VALUE (constVal ( + ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")), + resultType); + case CCR_OK: + default: + break; + } + } + /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */ - if (SPEC_USIGN(LETYPE(tree)) && - !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */ + if (tree->opval.op == '>' && + SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && - ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) - { - if (tree->opval.op == '<') - { - return tree->right; - } - if (tree->opval.op == '>') - { - if (resultType == RESULT_TYPE_IFX) - { - /* the parent is an ifx: */ - /* if (unsigned value) */ - return tree->left; - } - - /* (unsigned value) ? 1 : 0 */ - tree->opval.op = '?'; - tree->right = newNode (':', - newAst_VALUE (constVal ("1")), - tree->right); /* val 0 */ - tree->right->lineno = tree->lineno; - tree->right->left->lineno = tree->lineno; - decorateType (tree->right, RESULT_CHECK); - } + ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) + { + if (resultType == RESULT_TYPE_IFX) + { + /* the parent is an ifx: */ + /* if (unsigned value) */ + return tree->left; + } + + /* (unsigned value) ? 1 : 0 */ + tree->opval.op = '?'; + tree->right = newNode (':', + newAst_VALUE (constVal ("1")), + tree->right); /* val 0 */ + tree->right->lineno = tree->lineno; + tree->right->left->lineno = tree->lineno; + tree->decorated = 0; + return decorateType (tree, resultType); + } + + /* 'ifx (op == 0)' -> 'ifx (!(op))' */ + if (IS_LITERAL(RTYPE(tree)) && + floatFromVal (valFromType (RETYPE (tree))) == 0 && + tree->opval.op == EQ_OP && + resultType == RESULT_TYPE_IFX) + { + tree->opval.op = '!'; + tree->right = NULL; + tree->decorated = 0; + return decorateType (tree, resultType); } + /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && - IS_LITERAL (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = valCompare (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree)), - tree->opval.op); - tree->right = tree->left = NULL; - TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); - return tree; - } + IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valCompare (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree)), + tree->opval.op); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + + /* if one is 'signed char ' and the other one is 'unsigned char' */ + /* it's necessary to promote to int */ + if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) && + (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree)))) + { + /* Literals are 'optimized' to 'unsigned char'. Try to figure out, + if it's possible to use a 'signed char' */ + + /* is left a 'unsigned char'? */ + if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) && + /* the value range of a 'unsigned char' is 0...255; + if the actual value is < 128 it can be changed to signed */ + (int) floatFromVal (valFromType (RETYPE (tree))) < 128) + { + /* now we've got 2 'signed char'! */ + SPEC_USIGN (RETYPE (tree)) = 0; + } + /* same test for the left operand: */ + else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) && + (int) floatFromVal (valFromType (LETYPE (tree))) < 128) + { + SPEC_USIGN (LETYPE (tree)) = 0; + } + else + { + werror (W_CMP_SU_CHAR); + tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE); + tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE); + } + } + LRVAL (tree) = RRVAL (tree) = 1; - TTYPE (tree) = TETYPE (tree) = newCharLink (); + TTYPE (tree) = TETYPE (tree) = newBoolLink (); + + /* condition transformations */ + { + unsigned transformedOp = 0; + + switch (tree->opval.op) + { + case '<': /* transform (a < b) to !(a >= b) */ + if (port->lt_nge) + transformedOp = GE_OP; + break; + case '>': /* transform (a > b) to !(a <= b) */ + if (port->gt_nle) + transformedOp = LE_OP; + break; + case LE_OP: /* transform (a <= b) to !(a > b) */ + if (port->le_ngt) + transformedOp = '>'; + break; + case GE_OP: /* transform (a >= b) to !(a < b) */ + if (port->ge_nlt) + transformedOp = '<'; + break; + case NE_OP: /* transform (a != b) to !(a == b) */ + if (port->ne_neq) + transformedOp = EQ_OP; + break; + case EQ_OP: /* transform (a == b) to !(a != b) */ + if (port->eq_nne) + transformedOp = NE_OP; + break; + default: + break; + } + if (transformedOp) + { + tree->opval.op = transformedOp; + tree->decorated = 0; + tree = newNode ('!', tree, NULL); + tree->lineno = tree->left->lineno; + return decorateType (tree, resultType); + } + } + return tree; /*------------------------------------------------------------------*/ /*----------------------------*/ /* sizeof */ /*----------------------------*/ - case SIZEOF: /* evaluate wihout code generation */ + case SIZEOF: /* evaluate wihout code generation */ /* change the type to a integer */ { - int size = getSize (tree->right->ftype); - SNPRINTF(buffer, sizeof(buffer), "%d", size); - if (!size && !IS_VOID(tree->right->ftype)) - werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE); + int size = getSize (tree->right->ftype); + SNPRINTF(buffer, sizeof(buffer), "%d", size); + if (!size && !IS_VOID(tree->right->ftype)) + werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE); } tree->type = EX_VALUE; tree->opval.val = constVal (buffer); tree->right = tree->left = NULL; TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); + tree->opval.val->type); return tree; /*------------------------------------------------------------------*/ @@ -3798,77 +4275,80 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* typeof */ /*----------------------------*/ case TYPEOF: - /* return typeof enum value */ - tree->type = EX_VALUE; - { - int typeofv = 0; - if (IS_SPEC(tree->right->ftype)) { - switch (SPEC_NOUN(tree->right->ftype)) { - case V_INT: - if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG; - else typeofv = TYPEOF_INT; - break; - case V_FLOAT: - typeofv = TYPEOF_FLOAT; - break; - case V_CHAR: - typeofv = TYPEOF_CHAR; - break; - case V_VOID: - typeofv = TYPEOF_VOID; - break; - case V_STRUCT: - typeofv = TYPEOF_STRUCT; - break; - case V_BITFIELD: - typeofv = TYPEOF_BITFIELD; - break; - case V_BIT: - typeofv = TYPEOF_BIT; - break; - case V_SBIT: - typeofv = TYPEOF_SBIT; - break; - default: - break; - } - } else { - switch (DCL_TYPE(tree->right->ftype)) { - case POINTER: - typeofv = TYPEOF_POINTER; - break; - case FPOINTER: - typeofv = TYPEOF_FPOINTER; - break; - case CPOINTER: - typeofv = TYPEOF_CPOINTER; - break; - case GPOINTER: - typeofv = TYPEOF_GPOINTER; - break; - case PPOINTER: - typeofv = TYPEOF_PPOINTER; - break; - case IPOINTER: - typeofv = TYPEOF_IPOINTER; - break; - case ARRAY: - typeofv = TYPEOF_ARRAY; - break; - case FUNCTION: - typeofv = TYPEOF_FUNCTION; - break; - default: - break; - } - } - SNPRINTF (buffer, sizeof(buffer), "%d", typeofv); - tree->opval.val = constVal (buffer); - tree->right = tree->left = NULL; - TETYPE (tree) = getSpec (TTYPE (tree) = - tree->opval.val->type); - } - return tree; + /* return typeof enum value */ + tree->type = EX_VALUE; + { + int typeofv = 0; + if (IS_SPEC(tree->right->ftype)) { + switch (SPEC_NOUN(tree->right->ftype)) { + case V_INT: + if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG; + else typeofv = TYPEOF_INT; + break; + case V_FLOAT: + typeofv = TYPEOF_FLOAT; + break; + case V_FIXED16X16: + typeofv = TYPEOF_FIXED16X16; + break; + case V_CHAR: + typeofv = TYPEOF_CHAR; + break; + case V_VOID: + typeofv = TYPEOF_VOID; + break; + case V_STRUCT: + typeofv = TYPEOF_STRUCT; + break; + case V_BITFIELD: + typeofv = TYPEOF_BITFIELD; + break; + case V_BIT: + typeofv = TYPEOF_BIT; + break; + case V_SBIT: + typeofv = TYPEOF_SBIT; + break; + default: + break; + } + } else { + switch (DCL_TYPE(tree->right->ftype)) { + case POINTER: + typeofv = TYPEOF_POINTER; + break; + case FPOINTER: + typeofv = TYPEOF_FPOINTER; + break; + case CPOINTER: + typeofv = TYPEOF_CPOINTER; + break; + case GPOINTER: + typeofv = TYPEOF_GPOINTER; + break; + case PPOINTER: + typeofv = TYPEOF_PPOINTER; + break; + case IPOINTER: + typeofv = TYPEOF_IPOINTER; + break; + case ARRAY: + typeofv = TYPEOF_ARRAY; + break; + case FUNCTION: + typeofv = TYPEOF_FUNCTION; + break; + default: + break; + } + } + SNPRINTF (buffer, sizeof(buffer), "%d", typeofv); + tree->opval.val = constVal (buffer); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + } + return tree; /*------------------------------------------------------------------*/ /*----------------------------*/ /* conditional operator '?' */ @@ -3877,29 +4357,30 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* the type is value of the colon operator (on the right) */ assert (IS_COLON_OP (tree->right)); /* if already known then replace the tree : optimizer will do it - but faster to do it here */ + but faster to do it here */ if (IS_LITERAL (LTYPE (tree))) - { - if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) + { + if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) return decorateType (tree->right->left, resultTypeProp); - else - return decorateType (tree->right->right, resultTypeProp); - } + else + return decorateType (tree->right->right, resultTypeProp); + } else - { - tree->right = decorateType (tree->right, resultTypeProp); - TTYPE (tree) = RTYPE (tree); - TETYPE (tree) = getSpec (TTYPE (tree)); - } + { + tree->right = decorateType (tree->right, resultTypeProp); + TTYPE (tree) = RTYPE (tree); + TETYPE (tree) = getSpec (TTYPE (tree)); + } return tree; case ':': /* if they don't match we have a problem */ - if (compareType (LTYPE (tree), RTYPE (tree)) == 0) - { - werror (E_TYPE_MISMATCH, "conditional operator", " "); - goto errorTreeReturn; - } + if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) && + (compareType (RTYPE (tree), LTYPE (tree)) == 0)) + { + werror (E_TYPE_MISMATCH, "conditional operator", " "); + goto errorTreeReturn; + } TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), resultType, tree->opval.op); @@ -3916,22 +4397,22 @@ decorateType (ast * tree, RESULT_TYPE resultType) case DIV_ASSIGN: /* for these it must be both must be integral */ if (!IS_ARITHMETIC (LTYPE (tree)) || - !IS_ARITHMETIC (RTYPE (tree))) - { - werror (E_OPS_INTEGRAL); - goto errorTreeReturn; - } + !IS_ARITHMETIC (RTYPE (tree))) + { + werror (E_OPS_INTEGRAL); + goto errorTreeReturn; + } RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)); if (!tree->initMode && IS_CONSTANT (LTYPE (tree))) - werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/="); + werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/="); if (LRVAL (tree)) - { - werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/="); - goto errorTreeReturn; - } + { + werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/="); + goto errorTreeReturn; + } LLVAL (tree) = 1; return tree; @@ -3943,22 +4424,22 @@ decorateType (ast * tree, RESULT_TYPE resultType) case LEFT_ASSIGN: /* for these it must be both must be integral */ if (!IS_INTEGRAL (LTYPE (tree)) || - !IS_INTEGRAL (RTYPE (tree))) - { - werror (E_OPS_INTEGRAL); - goto errorTreeReturn; - } + !IS_INTEGRAL (RTYPE (tree))) + { + werror (E_OPS_INTEGRAL); + goto errorTreeReturn; + } RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) - werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<="); + werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<="); if (LRVAL (tree)) - { - werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<="); - goto errorTreeReturn; - } + { + werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<="); + goto errorTreeReturn; + } LLVAL (tree) = 1; return tree; @@ -3969,33 +4450,33 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case SUB_ASSIGN: if (!(IS_PTR (LTYPE (tree)) || - IS_ARITHMETIC (LTYPE (tree)))) - { - werror (E_PLUS_INVALID, "-="); - goto errorTreeReturn; - } + IS_ARITHMETIC (LTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-="); + goto errorTreeReturn; + } if (!(IS_PTR (RTYPE (tree)) || - IS_ARITHMETIC (RTYPE (tree)))) - { - werror (E_PLUS_INVALID, "-="); - goto errorTreeReturn; - } + IS_ARITHMETIC (RTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-="); + goto errorTreeReturn; + } RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree), - RESULT_TYPE_NOPROM, - tree->opval.op)); + computeType (LTYPE (tree), + RTYPE (tree), + RESULT_TYPE_NOPROM, + tree->opval.op)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) - werror (E_CODE_WRITE, "-="); + werror (E_CODE_WRITE, "-="); if (LRVAL (tree)) - { - werror (E_LVALUE_REQUIRED, "-="); - goto errorTreeReturn; - } + { + werror (E_LVALUE_REQUIRED, "-="); + goto errorTreeReturn; + } LLVAL (tree) = 1; return tree; @@ -4008,39 +4489,39 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* this is not a unary operation */ /* if both pointers then problem */ if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree))) - { - werror (E_PTR_PLUS_PTR); - goto errorTreeReturn; - } + { + werror (E_PTR_PLUS_PTR); + goto errorTreeReturn; + } if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree))) - { - werror (E_PLUS_INVALID, "+="); - goto errorTreeReturn; - } + { + werror (E_PLUS_INVALID, "+="); + goto errorTreeReturn; + } if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree))) - { - werror (E_PLUS_INVALID, "+="); - goto errorTreeReturn; - } + { + werror (E_PLUS_INVALID, "+="); + goto errorTreeReturn; + } RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree), - RESULT_TYPE_NOPROM, - tree->opval.op)); + computeType (LTYPE (tree), + RTYPE (tree), + RESULT_TYPE_NOPROM, + tree->opval.op)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) - werror (E_CODE_WRITE, "+="); + werror (E_CODE_WRITE, "+="); if (LRVAL (tree)) - { - werror (E_LVALUE_REQUIRED, "+="); - goto errorTreeReturn; - } + { + werror (E_LVALUE_REQUIRED, "+="); + goto errorTreeReturn; + } - tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK); + tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE); tree->opval.op = '='; return tree; @@ -4053,39 +4534,39 @@ decorateType (ast * tree, RESULT_TYPE resultType) case '=': /* cannot be an aggregate */ if (IS_AGGREGATE (LTYPE (tree))) - { - werror (E_AGGR_ASSIGN); - goto errorTreeReturn; - } + { + werror (E_AGGR_ASSIGN); + goto errorTreeReturn; + } /* they should either match or be castable */ if (compareType (LTYPE (tree), RTYPE (tree)) == 0) - { - werror (E_TYPE_MISMATCH, "assignment", " "); - printFromToType(RTYPE(tree),LTYPE(tree)); - } + { + werror (E_TYPE_MISMATCH, "assignment", " "); + printFromToType(RTYPE(tree),LTYPE(tree)); + } /* if the left side of the tree is of type void then report error */ if (IS_VOID (LTYPE (tree))) - { - werror (E_CAST_ZERO); - printFromToType(RTYPE(tree), LTYPE(tree)); - } + { + werror (E_CAST_ZERO); + printFromToType(RTYPE(tree), LTYPE(tree)); + } TETYPE (tree) = getSpec (TTYPE (tree) = - LTYPE (tree)); + LTYPE (tree)); RRVAL (tree) = 1; LLVAL (tree) = 1; if (!tree->initMode ) { if (IS_CONSTANT(LTYPE(tree))) - werror (E_CODE_WRITE, "="); + werror (E_CODE_WRITE, "="); } if (LRVAL (tree)) - { - werror (E_LVALUE_REQUIRED, "="); - goto errorTreeReturn; - } + { + werror (E_LVALUE_REQUIRED, "="); + goto errorTreeReturn; + } return tree; @@ -4102,32 +4583,34 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* function call */ /*----------------------------*/ case CALL: - + /* undo any explicit pointer derefernce; PCALL will handle it instead */ if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP) { - if (tree->left->opval.op == '*' && !tree->left->right) - tree->left = tree->left->left; - } + if (tree->left->opval.op == '*' && !tree->left->right) + tree->left = tree->left->left; + } /* require a function or pointer to function */ - if (!IS_FUNC (LTYPE (tree)) - && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next))) - { - werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED); - goto errorTreeReturn; - } + if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree))) + { + werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED); + goto errorTreeReturn; + } /* if there are parms, make sure that parms are decorate / process / reverse only once */ if (!tree->right || !tree->right->decorated) { - sym_link *functype; + sym_link *functype; parmNumber = 1; - if (IS_CODEPTR(LTYPE(tree))) - functype = LTYPE (tree)->next; + if (IS_FUNCPTR (LTYPE (tree))) + { + functype = LTYPE (tree)->next; + processFuncPtrArgs (functype); + } else functype = LTYPE (tree); @@ -4136,8 +4619,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) { goto errorTreeReturn; } - - if ((options.stackAuto || IFFUNC_ISREENT (functype)) && + + if ((options.stackAuto || IFFUNC_ISREENT (functype)) && !IFFUNC_ISBUILTIN(functype)) { reverseParms (tree->right); @@ -4154,32 +4637,32 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case RETURN: if (!tree->right) - goto voidcheck; + goto voidcheck; if (compareType (currFunc->type->next, RTYPE (tree)) == 0) - { - werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH); - printFromToType (RTYPE(tree), currFunc->type->next); - goto errorTreeReturn; - } + { + werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH); + printFromToType (RTYPE(tree), currFunc->type->next); + goto errorTreeReturn; + } if (IS_VOID (currFunc->type->next) - && tree->right && - !IS_VOID (RTYPE (tree))) - { - werrorfl (tree->filename, tree->lineno, E_FUNC_VOID); - goto errorTreeReturn; - } + && tree->right && + !IS_VOID (RTYPE (tree))) + { + werrorfl (tree->filename, tree->lineno, E_FUNC_VOID); + goto errorTreeReturn; + } /* if there is going to be a casting required then add it */ if (compareType (currFunc->type->next, RTYPE (tree)) < 0) - { - tree->right = - decorateType (newNode (CAST, - newAst_LINK (copyLinkChain (currFunc->type->next)), - tree->right), - RESULT_CHECK); - } + { + tree->right = + decorateType (newNode (CAST, + newAst_LINK (copyLinkChain (currFunc->type->next)), + tree->right), + RESULT_TYPE_NONE); + } RRVAL (tree) = 1; return tree; @@ -4187,10 +4670,10 @@ decorateType (ast * tree, RESULT_TYPE resultType) voidcheck: if (!IS_VOID (currFunc->type->next) && tree->right == NULL) - { - werror (W_VOID_FUNC, currFunc->name); - goto errorTreeReturn; - } + { + werror (W_VOID_FUNC, currFunc->name); + goto errorTreeReturn; + } TTYPE (tree) = TETYPE (tree) = NULL; return tree; @@ -4202,10 +4685,10 @@ decorateType (ast * tree, RESULT_TYPE resultType) case SWITCH: /* the switch value must be an integer */ if (!IS_INTEGRAL (LTYPE (tree))) - { - werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER); - goto errorTreeReturn; - } + { + werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER); + goto errorTreeReturn; + } LRVAL (tree) = 1; TTYPE (tree) = TETYPE (tree) = NULL; return tree; @@ -4216,8 +4699,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case IFX: tree->left = backPatchLabels (tree->left, - tree->trueLabel, - tree->falseLabel); + tree->trueLabel, + tree->falseLabel); TTYPE (tree) = TETYPE (tree) = NULL; return tree; @@ -4227,33 +4710,36 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case FOR: - decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK); - decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK); - decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK); + AST_FOR (tree, initExpr) = decorateType ( + resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE); + AST_FOR (tree, condExpr) = decorateType ( + resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE); + AST_FOR (tree, loopExpr) = decorateType ( + resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE); /* if the for loop is reversible then reverse it otherwise do what we normally do */ { - symbol *sym; - ast *init, *end; - - if (isLoopReversible (tree, &sym, &init, &end)) - return reverseLoop (tree, sym, init, end); - else - return decorateType (createFor (AST_FOR (tree, trueLabel), - AST_FOR (tree, continueLabel), - AST_FOR (tree, falseLabel), - AST_FOR (tree, condLabel), - AST_FOR (tree, initExpr), - AST_FOR (tree, condExpr), - AST_FOR (tree, loopExpr), - tree->left), RESULT_CHECK); + symbol *sym; + ast *init, *end; + + if (isLoopReversible (tree, &sym, &init, &end)) + return reverseLoop (tree, sym, init, end); + else + return decorateType (createFor (AST_FOR (tree, trueLabel), + AST_FOR (tree, continueLabel), + AST_FOR (tree, falseLabel), + AST_FOR (tree, condLabel), + AST_FOR (tree, initExpr), + AST_FOR (tree, condExpr), + AST_FOR (tree, loopExpr), + tree->left), RESULT_TYPE_NONE); } case PARAM: werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "node PARAM shouldn't be processed here"); - /* but in processParams() */ + "node PARAM shouldn't be processed here"); + /* but in processParams() */ return tree; default: TTYPE (tree) = TETYPE (tree) = NULL; @@ -4302,13 +4788,23 @@ sizeofOp (sym_link * type) /*-----------------------------------------------------------------*/ /* backPatchLabels - change and or not operators to flow control */ /*-----------------------------------------------------------------*/ -ast * +static ast * backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) { if (!tree) return NULL; + /* while-loops insert a label between the IFX and the condition, + therefore look behind the label too */ + if (tree->opval.op == LABEL && + tree->right && + IS_ANDORNOT (tree->right)) + { + tree->right = backPatchLabels (tree->right, trueLabel, falseLabel); + return tree; + } + if (!(IS_ANDORNOT (tree))) return tree; @@ -4325,12 +4821,12 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) /* if left is already a IFX then just change the if true label in that */ if (!IS_IFX (tree->left)) - tree->left = newIfxNode (tree->left, localLabel, falseLabel); + tree->left = newIfxNode (tree->left, localLabel, falseLabel); tree->right = backPatchLabels (tree->right, trueLabel, falseLabel); /* right is a IFX then just join */ if (IS_IFX (tree->right)) - return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right)); + return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right)); tree->right = createLabel (localLabel, tree->right); tree->right = newIfxNode (tree->right, trueLabel, falseLabel); @@ -4351,12 +4847,12 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) /* if left is already a IFX then just change the if true label in that */ if (!IS_IFX (tree->left)) - tree->left = newIfxNode (tree->left, trueLabel, localLabel); + tree->left = newIfxNode (tree->left, trueLabel, localLabel); tree->right = backPatchLabels (tree->right, trueLabel, falseLabel); /* right is a IFX then just join */ if (IS_IFX (tree->right)) - return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right)); + return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right)); tree->right = createLabel (localLabel, tree->right); tree->right = newIfxNode (tree->right, trueLabel, falseLabel); @@ -4367,25 +4863,18 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) /* change not */ if (IS_NOT (tree)) { - int wasnot = IS_NOT (tree->left); + /* call with exchanged labels */ tree->left = backPatchLabels (tree->left, falseLabel, trueLabel); - /* if the left is already a IFX */ + /* if left isn't already a IFX */ if (!IS_IFX (tree->left)) - tree->left = newNode (IFX, tree->left, NULL); - - if (wasnot) - { - tree->left->trueLabel = trueLabel; - tree->left->falseLabel = falseLabel; - } - else - { - tree->left->trueLabel = falseLabel; - tree->left->falseLabel = trueLabel; - } + { + tree->left = newNode (IFX, tree->left, NULL); + tree->left->trueLabel = falseLabel; + tree->left->falseLabel = trueLabel; + } return tree->left; - } + } if (IS_IFX (tree)) { @@ -4411,8 +4900,7 @@ createBlock (symbol * decl, ast * body) ex = newNode (BLOCK, NULL, body); ex->values.sym = decl; - - ex->right = ex->right; + ex->level++; ex->lineno = 0; return ex; @@ -4473,7 +4961,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) return NULL; } - caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK); + caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE); /* if not a constant then error */ if (!IS_LITERAL (caseVal->ftype)) { @@ -4497,44 +4985,44 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) value *pval = NULL; int cVal = (int) floatFromVal (caseVal->opval.val); while (val && (int) floatFromVal (val) < cVal) - { - pval = val; - val = val->next; - } + { + pval = val; + val = val->next; + } /* if we reached the end then */ if (!val) - { - pval->next = caseVal->opval.val; - } + { + pval->next = caseVal->opval.val; + } else if ((int) floatFromVal (val) == cVal) - { - werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL, - "case"); - return NULL; - } + { + werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL, + "case"); + return NULL; + } else - { - /* we found a value greater than */ - /* the current value we must add this */ - /* before the value */ - caseVal->opval.val->next = val; - - /* if this was the first in chain */ - if (swStat->values.switchVals.swVals == val) - swStat->values.switchVals.swVals = - caseVal->opval.val; - else - pval->next = caseVal->opval.val; - } + { + /* we found a value greater than */ + /* the current value we must add this */ + /* before the value */ + caseVal->opval.val->next = val; + + /* if this was the first in chain */ + if (swStat->values.switchVals.swVals == val) + swStat->values.switchVals.swVals = + caseVal->opval.val; + else + pval->next = caseVal->opval.val; + } } /* create the case label */ - SNPRINTF(caseLbl, sizeof(caseLbl), - "_case_%d_%d", - swStat->values.switchVals.swNum, - (int) floatFromVal (caseVal->opval.val)); + SNPRINTF(caseLbl, sizeof(caseLbl), + "_case_%d_%d", + swStat->values.switchVals.swNum, + (int) floatFromVal (caseVal->opval.val)); rexpr = createLabel (newSymbol (caseLbl, 0), stmnt); rexpr->lineno = 0; @@ -4560,7 +5048,7 @@ createDefault (ast * swStat, ast * defaultVal, ast * stmnt) if (swStat->values.switchVals.swDefault) { werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL, - "default"); + "default"); return NULL; } @@ -4569,7 +5057,7 @@ createDefault (ast * swStat, ast * defaultVal, ast * stmnt) /* create the label */ SNPRINTF (defLbl, sizeof(defLbl), - "_default_%d", swStat->values.switchVals.swNum); + "_default_%d", swStat->values.switchVals.swNum); return createLabel (newSymbol (defLbl, 0), stmnt); } @@ -4614,20 +5102,20 @@ createIf (ast * condAst, ast * ifBody, ast * elseBody) if (elseBody) { ifBody = newNode (NULLOP, ifBody, - newNode (GOTO, - newAst_VALUE (symbolVal (ifEnd)), - NULL)); + newNode (GOTO, + newAst_VALUE (symbolVal (ifEnd)), + NULL)); /* put the elseLabel on the else body */ elseBody = createLabel (ifFalse, elseBody); /* out the end at the end of the body */ elseBody = newNode (NULLOP, - elseBody, - createLabel (ifEnd, NULL)); + elseBody, + createLabel (ifEnd, NULL)); } else { ifBody = newNode (NULLOP, ifBody, - createLabel (ifFalse, NULL)); + createLabel (ifFalse, NULL)); } condAst = backPatchLabels (condAst, ifTrue, ifFalse); if (IS_IFX (condAst)) @@ -4636,7 +5124,7 @@ createIf (ast * condAst, ast * ifBody, ast * elseBody) ifTree = newIfxNode (condAst, ifTrue, ifFalse); return newNode (NULLOP, ifTree, - newNode (NULLOP, ifBody, elseBody)); + newNode (NULLOP, ifBody, elseBody)); } @@ -4652,7 +5140,7 @@ createIf (ast * condAst, ast * ifBody, ast * elseBody) /*-----------------------------------------------------------------*/ ast * createDo (symbol * trueLabel, symbol * continueLabel, - symbol * falseLabel, ast * condAst, ast * doBody) + symbol * falseLabel, ast * condAst, ast * doBody) { ast *doTree; @@ -4662,7 +5150,7 @@ createDo (symbol * trueLabel, symbol * continueLabel, { condAst = backPatchLabels (condAst, continueLabel, NULL); doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst) - : newNode (IFX, createLabel (continueLabel, condAst), NULL)); + : newNode (IFX, createLabel (continueLabel, condAst), NULL)); doTree->trueLabel = continueLabel; doTree->falseLabel = NULL; return doTree; @@ -4675,7 +5163,7 @@ createDo (symbol * trueLabel, symbol * continueLabel, doBody = createLabel (trueLabel, doBody); /* attach the continue label to end of body */ doBody = newNode (NULLOP, doBody, - createLabel (continueLabel, NULL)); + createLabel (continueLabel, NULL)); /* now put the break label at the end */ if (IS_IFX (condAst)) @@ -4705,9 +5193,9 @@ createDo (symbol * trueLabel, symbol * continueLabel, /*-----------------------------------------------------------------*/ ast * createFor (symbol * trueLabel, symbol * continueLabel, - symbol * falseLabel, symbol * condLabel, - ast * initExpr, ast * condExpr, ast * loopExpr, - ast * forBody) + symbol * falseLabel, symbol * condLabel, + ast * initExpr, ast * condExpr, ast * loopExpr, + ast * forBody) { ast *forTree; @@ -4715,8 +5203,8 @@ createFor (symbol * trueLabel, symbol * continueLabel, /* the same way as a while */ if (!loopExpr) return newNode (NULLOP, initExpr, - createWhile (trueLabel, continueLabel, - falseLabel, condExpr, forBody)); + createWhile (trueLabel, continueLabel, + falseLabel, condExpr, forBody)); /* vanilla for statement */ condExpr = backPatchLabels (condExpr, trueLabel, falseLabel); @@ -4733,18 +5221,18 @@ createFor (symbol * trueLabel, symbol * continueLabel, /* attach continue to forLoop expression & attach */ /* goto the forcond @ and of loopExpression */ loopExpr = createLabel (continueLabel, - newNode (NULLOP, - loopExpr, - newNode (GOTO, - newAst_VALUE (symbolVal (condLabel)), - NULL))); + newNode (NULLOP, + loopExpr, + newNode (GOTO, + newAst_VALUE (symbolVal (condLabel)), + NULL))); /* now start putting them together */ forTree = newNode (NULLOP, initExpr, condExpr); forTree = newNode (NULLOP, forTree, forBody); forTree = newNode (NULLOP, forTree, loopExpr); /* finally add the break label */ forTree = newNode (NULLOP, forTree, - createLabel (falseLabel, NULL)); + createLabel (falseLabel, NULL)); return forTree; } @@ -4763,7 +5251,7 @@ createFor (symbol * trueLabel, symbol * continueLabel, /*-----------------------------------------------------------------*/ ast * createWhile (symbol * trueLabel, symbol * continueLabel, - symbol * falseLabel, ast * condExpr, ast * whileBody) + symbol * falseLabel, ast * condExpr, ast * whileBody) { ast *whileTree; @@ -4778,10 +5266,10 @@ createWhile (symbol * trueLabel, symbol * continueLabel, /* put a jump to continue at the end of the body */ /* and put break label at the end of the body */ whileBody = newNode (NULLOP, - whileBody, - newNode (GOTO, - newAst_VALUE (symbolVal (continueLabel)), - createLabel (falseLabel, NULL))); + whileBody, + newNode (GOTO, + newAst_VALUE (symbolVal (continueLabel)), + createLabel (falseLabel, NULL))); /* put it all together */ if (IS_IFX (condExpr)) @@ -4798,41 +5286,194 @@ createWhile (symbol * trueLabel, symbol * continueLabel, } /*-----------------------------------------------------------------*/ -/* optimizeGetHbit - get highest order bit of the expression */ +/* isShiftRightLitVal _BitAndLitVal - helper function */ /*-----------------------------------------------------------------*/ -ast * -optimizeGetHbit (ast * tree) +static ast * +isShiftRightLitVal_BitAndLitVal (ast * tree) { - int i, j; /* if this is not a bit and */ if (!IS_BITAND (tree)) - return tree; + return NULL; + + /* will look for tree of the form + ( expr >> litval2) & litval1 */ + if (!IS_AST_LIT_VALUE (tree->right)) + return NULL; + + if (!IS_RIGHT_OP (tree->left)) + return NULL; + + if (!IS_AST_LIT_VALUE (tree->left->right)) + return NULL; + + return tree->left->left; +} + +/*-----------------------------------------------------------------*/ +/* isBitAndPowOf2 - helper function */ +/*-----------------------------------------------------------------*/ +static int +isBitAndPow2 (ast * tree) +{ + /* if this is not a bit and */ + if (!IS_BITAND (tree)) + return -1; /* will look for tree of the form - ( expr >> ((sizeof expr) -1) ) & 1 */ + ( expr & (1 << litval) */ if (!IS_AST_LIT_VALUE (tree->right)) + return -1; + + return powof2 ((TYPE_TARGET_ULONG)AST_LIT_VALUE (tree->right)); +} + +/*-----------------------------------------------------------------*/ +/* optimizeGetHbit - get highest order bit of the expression */ +/*-----------------------------------------------------------------*/ +ast * +optimizeGetHbit (ast * tree, RESULT_TYPE resultType) +{ + int i, j; + ast * expr; + + expr = isShiftRightLitVal_BitAndLitVal(tree); + if (expr) + { + if ((AST_LIT_VALUE (tree->right) != 1) || + ((i = (int) AST_LIT_VALUE (tree->left->right)) != + (j = (getSize (TTYPE (expr)) * 8 - 1)))) + expr = NULL; + } + if (!expr && (resultType == RESULT_TYPE_BIT)) + { + expr = tree->left; + if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1) + expr = NULL; + } + if (!expr) return tree; - if (AST_LIT_VALUE (tree->right) != 1) + /* make sure the port supports GETHBIT */ + if (port->hasExtBitOp + && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr)))) return tree; - if (!IS_RIGHT_OP (tree->left)) + return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE); +} + +/*-----------------------------------------------------------------*/ +/* optimizeGetAbit - get a single bit of the expression */ +/*-----------------------------------------------------------------*/ +ast * +optimizeGetAbit (ast * tree, RESULT_TYPE resultType) +{ + ast * expr; + ast * count = NULL; + + expr = isShiftRightLitVal_BitAndLitVal(tree); + if (expr) + { + if (AST_LIT_VALUE (tree->right) != 1) + expr = NULL; + count = tree->left->right; + } + if (!expr && (resultType == RESULT_TYPE_BIT)) + { + int p2 = isBitAndPow2 (tree); + if (p2 >= 0) + { + expr = tree->left; + count = newAst_VALUE (valueFromLit (p2)); + } + } + if (!expr) return tree; - if (!IS_AST_LIT_VALUE (tree->left->right)) + /* make sure the port supports GETABIT */ + if (port->hasExtBitOp + && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr)))) return tree; - if ((i = (int) AST_LIT_VALUE (tree->left->right)) != - (j = (getSize (TTYPE (tree->left->left)) * 8 - 1))) + return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE); + +} + +/*-----------------------------------------------------------------*/ +/* optimizeGetByte - get a byte of the expression */ +/*-----------------------------------------------------------------*/ +ast * +optimizeGetByte (ast * tree, RESULT_TYPE resultType) +{ + unsigned int i = 0; + ast * expr; + ast * count = NULL; + + expr = isShiftRightLitVal_BitAndLitVal(tree); + if (expr) + { + i = (unsigned int) AST_LIT_VALUE (tree->left->right); + count = tree->left->right; + if (AST_LIT_VALUE (tree->right) != 0xFF) + expr = NULL; + } + if (!expr && resultType == RESULT_TYPE_CHAR) + { + /* if this is a right shift over a multiple of 8 */ + if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right)) + { + i = (unsigned int) AST_LIT_VALUE (tree->right); + count = tree->right; + expr = tree->left; + } + } + if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8)) return tree; - - /* make sure the port supports GETHBIT */ + + /* make sure the port supports GETBYTE */ if (port->hasExtBitOp - && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left)))) + && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr)))) + return tree; + + return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE); +} + +/*-----------------------------------------------------------------*/ +/* optimizeGetWord - get two bytes of the expression */ +/*-----------------------------------------------------------------*/ +ast * +optimizeGetWord (ast * tree, RESULT_TYPE resultType) +{ + unsigned int i = 0; + ast * expr; + ast * count = NULL; + + expr = isShiftRightLitVal_BitAndLitVal(tree); + if (expr) + { + i = (unsigned int) AST_LIT_VALUE (tree->left->right); + count = tree->left->right; + if (AST_LIT_VALUE (tree->right) != 0xFFFF) + expr = NULL; + } + if (!expr && resultType == RESULT_TYPE_INT) + { + /* if this is a right shift over a multiple of 8 */ + if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right)) + { + i = (unsigned int) AST_LIT_VALUE (tree->right); + count = tree->right; + expr = tree->left; + } + } + if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8)) return tree; - return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK); + /* make sure the port supports GETWORD */ + if (port->hasExtBitOp + && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr)))) + return tree; + return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE); } /*-----------------------------------------------------------------*/ @@ -4851,12 +5492,12 @@ optimizeRRCRLC (ast * root) into a RRC operation note : by 7 I mean (number of bits required to hold the variable -1 ) */ - /* if the root operations is not a | operation the not */ + /* if the root operation is not a | operation then not */ if (!IS_BITOR (root)) return root; /* I have to think of a better way to match patterns this sucks */ - /* that aside let start looking for the first case : I use a the + /* that aside let's start looking for the first case : I use a negative check a lot to improve the efficiency */ /* (?expr << 1) | (?expr >> 7) */ if (IS_LEFT_OP (root->left) && @@ -4864,23 +5505,23 @@ optimizeRRCRLC (ast * root) { if (!SPEC_USIGN (TETYPE (root->left->left))) - return root; + return root; if (!IS_AST_LIT_VALUE (root->left->right) || - !IS_AST_LIT_VALUE (root->right->right)) - goto tryNext0; + !IS_AST_LIT_VALUE (root->right->right)) + goto tryNext0; /* make sure it is the same expression */ if (!isAstEqual (root->left->left, - root->right->left)) - goto tryNext0; + root->right->left)) + goto tryNext0; if (AST_LIT_VALUE (root->left->right) != 1) - goto tryNext0; + goto tryNext0; if (AST_LIT_VALUE (root->right->right) != - (getSize (TTYPE (root->left->left)) * 8 - 1)) - goto tryNext0; + (getSize (TTYPE (root->left->left)) * 8 - 1)) + goto tryNext0; /* make sure the port supports RLC */ if (port->hasExtBitOp @@ -4899,23 +5540,23 @@ tryNext0: { if (!SPEC_USIGN (TETYPE (root->left->left))) - return root; + return root; if (!IS_AST_LIT_VALUE (root->left->right) || - !IS_AST_LIT_VALUE (root->right->right)) - goto tryNext1; + !IS_AST_LIT_VALUE (root->right->right)) + goto tryNext1; /* make sure it is the same symbol */ if (!isAstEqual (root->left->left, - root->right->left)) - goto tryNext1; + root->right->left)) + goto tryNext1; if (AST_LIT_VALUE (root->right->right) != 1) - goto tryNext1; + goto tryNext1; if (AST_LIT_VALUE (root->left->right) != - (getSize (TTYPE (root->left->left)) * 8 - 1)) - goto tryNext1; + (getSize (TTYPE (root->left->left)) * 8 - 1)) + goto tryNext1; /* make sure the port supports RLC */ if (port->hasExtBitOp @@ -4935,23 +5576,23 @@ tryNext1: { if (!SPEC_USIGN (TETYPE (root->left->left))) - return root; + return root; if (!IS_AST_LIT_VALUE (root->left->right) || - !IS_AST_LIT_VALUE (root->right->right)) - goto tryNext2; + !IS_AST_LIT_VALUE (root->right->right)) + goto tryNext2; /* make sure it is the same symbol */ if (!isAstEqual (root->left->left, - root->right->left)) - goto tryNext2; + root->right->left)) + goto tryNext2; if (AST_LIT_VALUE (root->left->right) != 1) - goto tryNext2; + goto tryNext2; if (AST_LIT_VALUE (root->right->right) != - (getSize (TTYPE (root->left->left)) * 8 - 1)) - goto tryNext2; + (getSize (TTYPE (root->left->left)) * 8 - 1)) + goto tryNext2; /* make sure the port supports RRC */ if (port->hasExtBitOp @@ -4970,23 +5611,23 @@ tryNext2: { if (!SPEC_USIGN (TETYPE (root->left->left))) - return root; + return root; if (!IS_AST_LIT_VALUE (root->left->right) || - !IS_AST_LIT_VALUE (root->right->right)) - return root; + !IS_AST_LIT_VALUE (root->right->right)) + return root; /* make sure it is the same symbol */ if (!isAstEqual (root->left->left, - root->right->left)) - return root; + root->right->left)) + return root; if (AST_LIT_VALUE (root->right->right) != 1) - return root; + return root; if (AST_LIT_VALUE (root->left->right) != - (getSize (TTYPE (root->left->left)) * 8 - 1)) - return root; + (getSize (TTYPE (root->left->left)) * 8 - 1)) + return root; /* make sure the port supports RRC */ if (port->hasExtBitOp @@ -5014,7 +5655,7 @@ optimizeSWAP (ast * root) into a SWAP : operation .. note : by 4 I mean (number of bits required to hold the variable /2 ) */ - /* if the root operations is not a | operation the not */ + /* if the root operation is not a | operation then not */ if (!IS_BITOR (root)) return root; @@ -5024,24 +5665,24 @@ optimizeSWAP (ast * root) { if (!SPEC_USIGN (TETYPE (root->left->left))) - return root; + return root; if (!IS_AST_LIT_VALUE (root->left->right) || - !IS_AST_LIT_VALUE (root->right->right)) - return root; + !IS_AST_LIT_VALUE (root->right->right)) + return root; /* make sure it is the same expression */ if (!isAstEqual (root->left->left, - root->right->left)) - return root; + root->right->left)) + return root; if (AST_LIT_VALUE (root->left->right) != - (getSize (TTYPE (root->left->left)) * 4)) - return root; + (getSize (TTYPE (root->left->left)) * 4)) + return root; if (AST_LIT_VALUE (root->right->right) != - (getSize (TTYPE (root->left->left)) * 4)) - return root; + (getSize (TTYPE (root->left->left)) * 4)) + return root; /* make sure the port supports SWAP */ if (port->hasExtBitOp @@ -5058,7 +5699,7 @@ optimizeSWAP (ast * root) } /*-----------------------------------------------------------------*/ -/* optimizeCompare - otimizes compares for bit variables */ +/* optimizeCompare - optimizes compares for bit variables */ /*-----------------------------------------------------------------*/ static ast * optimizeCompare (ast * root) @@ -5085,27 +5726,27 @@ optimizeCompare (ast * root) if (isAstEqual (root->left, root->right)) { switch (root->opval.op) - { - case '>': - case '<': - case NE_OP: - optExpr = newAst_VALUE (constVal ("0")); - break; - case GE_OP: - case LE_OP: - case EQ_OP: - optExpr = newAst_VALUE (constVal ("1")); - break; - } - - return decorateType (optExpr, RESULT_CHECK); + { + case '>': + case '<': + case NE_OP: + optExpr = newAst_VALUE (constVal ("0")); + break; + case GE_OP: + case LE_OP: + case EQ_OP: + optExpr = newAst_VALUE (constVal ("1")); + break; + } + + return decorateType (optExpr, RESULT_TYPE_NONE); } vleft = (root->left->type == EX_VALUE ? - root->left->opval.val : NULL); + root->left->opval.val : NULL); vright = (root->right->type == EX_VALUE ? - root->right->opval.val : NULL); + root->right->opval.val : NULL); /* if left is a BITVAR in BITSPACE */ /* and right is a LITERAL then opt- */ @@ -5118,62 +5759,62 @@ optimizeCompare (ast * root) /* if right side > 1 then comparison may never succeed */ if ((litValue = (int) floatFromVal (vright)) > 1) - { - werror (W_BAD_COMPARE); - goto noOptimize; - } + { + werror (W_BAD_COMPARE); + goto noOptimize; + } if (litValue) - { - switch (root->opval.op) - { - case '>': /* bit value greater than 1 cannot be */ - werror (W_BAD_COMPARE); - goto noOptimize; - break; - - case '<': /* bit value < 1 means 0 */ - case NE_OP: - optExpr = newNode ('!', newAst_VALUE (vleft), NULL); - break; - - case LE_OP: /* bit value <= 1 means no check */ - optExpr = newAst_VALUE (vright); - break; - - case GE_OP: /* bit value >= 1 means only check for = */ - case EQ_OP: - optExpr = newAst_VALUE (vleft); - break; - } - } + { + switch (root->opval.op) + { + case '>': /* bit value greater than 1 cannot be */ + werror (W_BAD_COMPARE); + goto noOptimize; + break; + + case '<': /* bit value < 1 means 0 */ + case NE_OP: + optExpr = newNode ('!', newAst_VALUE (vleft), NULL); + break; + + case LE_OP: /* bit value <= 1 means no check */ + optExpr = newAst_VALUE (vright); + break; + + case GE_OP: /* bit value >= 1 means only check for = */ + case EQ_OP: + optExpr = newAst_VALUE (vleft); + break; + } + } else - { /* literal is zero */ - switch (root->opval.op) - { - case '<': /* bit value < 0 cannot be */ - werror (W_BAD_COMPARE); - goto noOptimize; - break; - - case '>': /* bit value > 0 means 1 */ - case NE_OP: - optExpr = newAst_VALUE (vleft); - break; - - case LE_OP: /* bit value <= 0 means no check */ - case GE_OP: /* bit value >= 0 means no check */ - werror (W_BAD_COMPARE); - goto noOptimize; - break; - - case EQ_OP: /* bit == 0 means ! of bit */ - optExpr = newNode ('!', newAst_VALUE (vleft), NULL); - break; - } - } - return decorateType (resolveSymbols (optExpr), RESULT_CHECK); - } /* end-of-if of BITVAR */ + { /* literal is zero */ + switch (root->opval.op) + { + case '<': /* bit value < 0 cannot be */ + werror (W_BAD_COMPARE); + goto noOptimize; + break; + + case '>': /* bit value > 0 means 1 */ + case NE_OP: + optExpr = newAst_VALUE (vleft); + break; + + case LE_OP: /* bit value <= 0 means no check */ + case GE_OP: /* bit value >= 0 means no check */ + werror (W_BAD_COMPARE); + goto noOptimize; + break; + + case EQ_OP: /* bit == 0 means ! of bit */ + optExpr = newNode ('!', newAst_VALUE (vleft), NULL); + break; + } + } + return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE); + } /* end-of-if of BITVAR */ noOptimize: return root; @@ -5181,7 +5822,7 @@ noOptimize: /*-----------------------------------------------------------------*/ /* addSymToBlock : adds the symbol to the first block we find */ /*-----------------------------------------------------------------*/ -void +void addSymToBlock (symbol * sym, ast * tree) { /* reached end of tree or a leaf */ @@ -5207,13 +5848,13 @@ addSymToBlock (symbol * sym, ast * tree) /*-----------------------------------------------------------------*/ /* processRegParms - do processing for register parameters */ /*-----------------------------------------------------------------*/ -static void +static void processRegParms (value * args, ast * body) { while (args) { if (IS_REGPARM (args->etype)) - addSymToBlock (args->sym, body); + addSymToBlock (args->sym, body); args = args->next; } } @@ -5269,34 +5910,39 @@ createFunction (symbol * name, ast * body) actually means we are now compiling the compiler support routine */ if (name->cdef) - { - addSet (&publics, name); - } + { + addSet (&publics, name); + } } else { - addSymChain (name); + addSymChain (&name); allocVariables (name); } name->lastLine = mylineno; currFunc = name; /* set the stack pointer */ - /* PENDING: check this for the mcs51 */ - stackPtr = -port->stack.direction * port->stack.call_overhead; + stackPtr = -port->stack.direction * port->stack.call_overhead; + xstackPtr = 0; + if (IFFUNC_ISISR (name->type)) stackPtr -= port->stack.direction * port->stack.isr_overhead; - if (IFFUNC_ISREENT (name->type) || options.stackAuto) - stackPtr -= port->stack.direction * port->stack.reent_overhead; - xstackPtr = -port->stack.direction * port->stack.call_overhead; + if (IFFUNC_ISREENT (name->type) || options.stackAuto) + { + if (options.useXstack) + xstackPtr -= port->stack.direction * port->stack.reent_overhead; + else + stackPtr -= port->stack.direction * port->stack.reent_overhead; + } - fetype = getSpec (name->type); /* get the specifier for the function */ + fetype = getSpec (name->type); /* get the specifier for the function */ /* if this is a reentrant function then */ if (IFFUNC_ISREENT (name->type)) reentrant++; - allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */ + allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */ /* do processing for parameters that are passed in registers */ processRegParms (FUNC_ARGS(name->type), body); @@ -5305,23 +5951,24 @@ createFunction (symbol * name, ast * body) stackPtr = 0; xstackPtr = -1; + gatherImplicitVariables (body, NULL); /* move implicit variables into blocks */ + /* allocate & autoinit the block variables */ processBlockVars (body, &stack, ALLOCATE); + /* name needs to be mangled */ + SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name); + + body = resolveSymbols (body); /* resolve the symbols */ + body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */ + /* save the stack information */ if (options.useXstack) name->xstack = SPEC_STAK (fetype) = stack; else name->stack = SPEC_STAK (fetype) = stack; - /* name needs to be mangled */ - SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name); - - body = resolveSymbols (body); /* resolve the symbols */ - body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */ - - - ex = newAst_VALUE (symbolVal (name)); /* create name */ + ex = newAst_VALUE (symbolVal (name)); /* create name */ ex = newNode (FUNCTION, ex, body); ex->values.args = FUNC_ARGS(name->type); ex->decorated=1; @@ -5350,7 +5997,7 @@ createFunction (symbol * name, ast * body) { GcurMemmap = statsg; codeOutFile = statsg->oFile; - eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK))); + eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE))); staticAutos = NULL; } @@ -5394,697 +6041,718 @@ skipall: void ast_print (ast * tree, FILE *outfile, int indent) { - if (!tree) return ; - - /* can print only decorated trees */ - if (!tree->decorated) return; - - /* if any child is an error | this one is an error do nothing */ - if (tree->isError || - (tree->left && tree->left->isError) || - (tree->right && tree->right->isError)) { - fprintf(outfile,"ERROR_NODE(%p)\n",tree); - } - - - /* print the line */ - /* if not block & function */ - if (tree->type == EX_OP && - (tree->opval.op != FUNCTION && - tree->opval.op != BLOCK && - tree->opval.op != NULLOP)) { - } - - if (tree->opval.op == FUNCTION) { - int arg=0; - value *args=FUNC_ARGS(tree->left->opval.val->type); - fprintf(outfile,"FUNCTION (%s=%p) type (", - tree->left->opval.val->name, tree); - printTypeChain (tree->left->opval.val->type->next,outfile); - fprintf(outfile,") args ("); - do { - if (arg) { - fprintf (outfile, ", "); - } - printTypeChain (args ? args->type : NULL, outfile); - arg++; - args= args ? args->next : NULL; - } while (args); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent); - ast_print(tree->right,outfile,indent); - return ; - } - if (tree->opval.op == BLOCK) { - symbol *decls = tree->values.sym; - INDENT(indent,outfile); - fprintf(outfile,"{\n"); - while (decls) { - INDENT(indent+2,outfile); - fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (", - decls->name, decls); - printTypeChain(decls->type,outfile); - fprintf(outfile,")\n"); - - decls = decls->next; - } - ast_print(tree->right,outfile,indent+2); - INDENT(indent,outfile); - fprintf(outfile,"}\n"); - return; - } - if (tree->opval.op == NULLOP) { - ast_print(tree->left,outfile,indent); - ast_print(tree->right,outfile,indent); - return ; - } - INDENT(indent,outfile); - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* leaf has been reached */ - /*----------------------------*/ - /* if this is of type value */ - /* just get the type */ - if (tree->type == EX_VALUE) { - - if (IS_LITERAL (tree->opval.val->etype)) { - fprintf(outfile,"CONSTANT (%p) value = ", tree); - if (SPEC_USIGN (tree->opval.val->etype)) - fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val)); - else - fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val)); - fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val), - floatFromVal(tree->opval.val)); - } else if (tree->opval.val->sym) { - /* if the undefined flag is set then give error message */ - if (tree->opval.val->sym->undefined) { - fprintf(outfile,"UNDEFINED SYMBOL "); - } else { - fprintf(outfile,"SYMBOL "); - } - fprintf(outfile,"(%s=%p)", - tree->opval.val->sym->name,tree); - } - if (tree->ftype) { - fprintf(outfile," type ("); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - } else { - fprintf(outfile,"\n"); - } - return ; - } - - /* if type link for the case of cast */ - if (tree->type == EX_LINK) { - fprintf(outfile,"TYPENODE (%p) type = (",tree); - printTypeChain(tree->opval.lnk,outfile); - fprintf(outfile,")\n"); - return ; - } - - - /* depending on type of operator do */ - - switch (tree->opval.op) { - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* array node */ - /*----------------------------*/ - case '[': - fprintf(outfile,"ARRAY_OP (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* struct/union */ - /*----------------------------*/ - case '.': - fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* struct/union pointer */ - /*----------------------------*/ - case PTR_OP: - fprintf(outfile,"PTR_ACCESS (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* ++/-- operation */ - /*----------------------------*/ - case INC_OP: - if (tree->left) - fprintf(outfile,"post-"); - else - fprintf(outfile,"pre-"); - fprintf(outfile,"INC_OP (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); /* postincrement case */ - ast_print(tree->right,outfile,indent+2); /* preincrement case */ - return ; - - case DEC_OP: - if (tree->left) - fprintf(outfile,"post-"); - else - fprintf(outfile,"pre-"); - fprintf(outfile,"DEC_OP (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); /* postdecrement case */ - ast_print(tree->right,outfile,indent+2); /* predecrement case */ - return ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* bitwise and */ - /*----------------------------*/ - case '&': - if (tree->right) { - fprintf(outfile,"& (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - } else { - fprintf(outfile,"ADDRESS_OF (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - } - return ; - /*----------------------------*/ - /* bitwise or */ - /*----------------------------*/ - case '|': - fprintf(outfile,"OR (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* bitwise xor */ - /*----------------------------*/ - case '^': - fprintf(outfile,"XOR (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* division */ - /*----------------------------*/ - case '/': - fprintf(outfile,"DIV (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* modulus */ - /*----------------------------*/ - case '%': - fprintf(outfile,"MOD (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* address dereference */ - /*----------------------------*/ - case '*': /* can be unary : if right is null then unary operation */ - if (!tree->right) { - fprintf(outfile,"DEREF (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - return ; - } - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* multiplication */ - /*----------------------------*/ - fprintf(outfile,"MULT (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* unary '+' operator */ - /*----------------------------*/ - case '+': - /* if unary plus */ - if (!tree->right) { - fprintf(outfile,"UPLUS (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - } else { - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* addition */ - /*----------------------------*/ - fprintf(outfile,"ADD (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - } - return; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* unary '-' */ - /*----------------------------*/ - case '-': /* can be unary */ - if (!tree->right) { - fprintf(outfile,"UMINUS (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - } else { - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* subtraction */ - /*----------------------------*/ - fprintf(outfile,"SUB (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - } - return; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* compliment */ - /*----------------------------*/ - case '~': - fprintf(outfile,"COMPL (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* not */ - /*----------------------------*/ - case '!': - fprintf(outfile,"NOT (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* shift */ - /*----------------------------*/ - case RRC: - fprintf(outfile,"RRC (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - return ; - - case RLC: - fprintf(outfile,"RLC (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - return ; - case SWAP: - fprintf(outfile,"SWAP (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - return ; - case GETHBIT: - fprintf(outfile,"GETHBIT (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - return ; - case LEFT_OP: - fprintf(outfile,"LEFT_SHIFT (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - case RIGHT_OP: - fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* casting */ - /*----------------------------*/ - case CAST: /* change the type */ - fprintf(outfile,"CAST (%p) from type (",tree); - printTypeChain(tree->right->ftype,outfile); - fprintf(outfile,") to type ("); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->right,outfile,indent+2); - return ; - - case AND_OP: - fprintf(outfile,"ANDAND (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - case OR_OP: - fprintf(outfile,"OROR (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* comparison operators */ - /*----------------------------*/ - case '>': - fprintf(outfile,"GT(>) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - case '<': - fprintf(outfile,"LT(<) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - case LE_OP: - fprintf(outfile,"LE(<=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - case GE_OP: - fprintf(outfile,"GE(>=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - case EQ_OP: - fprintf(outfile,"EQ(==) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - case NE_OP: - fprintf(outfile,"NE(!=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* sizeof */ - /*----------------------------*/ - case SIZEOF: /* evaluate wihout code generation */ - fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype))); - return ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* conditional operator '?' */ - /*----------------------------*/ - case '?': - fprintf(outfile,"QUEST(?) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - - case ':': - fprintf(outfile,"COLON(:) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* assignment operators */ - /*----------------------------*/ - case MUL_ASSIGN: - fprintf(outfile,"MULASS(*=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - case DIV_ASSIGN: - fprintf(outfile,"DIVASS(/=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - case AND_ASSIGN: - fprintf(outfile,"ANDASS(&=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - case OR_ASSIGN: - fprintf(outfile,"ORASS(|=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - case XOR_ASSIGN: - fprintf(outfile,"XORASS(^=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - case RIGHT_ASSIGN: - fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - case LEFT_ASSIGN: - fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* -= operator */ - /*----------------------------*/ - case SUB_ASSIGN: - fprintf(outfile,"SUBASS(-=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* += operator */ - /*----------------------------*/ - case ADD_ASSIGN: - fprintf(outfile,"ADDASS(+=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* straight assignemnt */ - /*----------------------------*/ - case '=': - fprintf(outfile,"ASSIGN(=) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* comma operator */ - /*----------------------------*/ - case ',': - fprintf(outfile,"COMMA(,) (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* function call */ - /*----------------------------*/ - case CALL: - case PCALL: - fprintf(outfile,"CALL (%p) type (",tree); - printTypeChain(tree->ftype,outfile); - fprintf(outfile,")\n"); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent+2); - return; - case PARAM: - fprintf(outfile,"PARMS\n"); - ast_print(tree->left,outfile,indent+2); - if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) { - ast_print(tree->right,outfile,indent+2); - } - return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* return statement */ - /*----------------------------*/ - case RETURN: - fprintf(outfile,"RETURN (%p) type (",tree); - if (tree->right) { - printTypeChain(tree->right->ftype,outfile); - } - fprintf(outfile,")\n"); - ast_print(tree->right,outfile,indent+2); - return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* label statement */ - /*----------------------------*/ - case LABEL : - fprintf(outfile,"LABEL (%p)\n",tree); - ast_print(tree->left,outfile,indent+2); - ast_print(tree->right,outfile,indent); - return; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* switch statement */ - /*----------------------------*/ - case SWITCH: - { - value *val; - fprintf(outfile,"SWITCH (%p) ",tree); - ast_print(tree->left,outfile,0); - for (val = tree->values.switchVals.swVals; val ; val = val->next) { - INDENT(indent+2,outfile); - fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n", - (int) floatFromVal(val), - tree->values.switchVals.swNum, - (int) floatFromVal(val)); - } - ast_print(tree->right,outfile,indent); - } - return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* ifx Statement */ - /*----------------------------*/ - case IFX: - fprintf(outfile,"IF (%p) \n",tree); - ast_print(tree->left,outfile,indent+2); - if (tree->trueLabel) { - INDENT(indent+2,outfile); - fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name); - } - if (tree->falseLabel) { - INDENT(indent+2,outfile); - fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name); - } - ast_print(tree->right,outfile,indent+2); - return ; - /*----------------------------*/ - /* goto Statement */ - /*----------------------------*/ - case GOTO: - fprintf(outfile,"GOTO (%p) \n",tree); - ast_print(tree->left,outfile,indent+2); - fprintf(outfile,"\n"); - return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* for Statement */ - /*----------------------------*/ - case FOR: - fprintf(outfile,"FOR (%p) \n",tree); - if (AST_FOR( tree, initExpr)) { - INDENT(indent+2,outfile); - fprintf(outfile,"INIT EXPR "); - ast_print(AST_FOR(tree, initExpr),outfile,indent+2); - } - if (AST_FOR( tree, condExpr)) { - INDENT(indent+2,outfile); - fprintf(outfile,"COND EXPR "); - ast_print(AST_FOR(tree, condExpr),outfile,indent+2); - } - if (AST_FOR( tree, loopExpr)) { - INDENT(indent+2,outfile); - fprintf(outfile,"LOOP EXPR "); - ast_print(AST_FOR(tree, loopExpr),outfile,indent+2); - } - fprintf(outfile,"FOR LOOP BODY \n"); - ast_print(tree->left,outfile,indent+2); - return ; - case CRITICAL: - fprintf(outfile,"CRITICAL (%p) \n",tree); - ast_print(tree->left,outfile,indent+2); - default: - return ; - } + if (!tree) return ; + + /* can print only decorated trees */ + if (!tree->decorated) return; + + /* if any child is an error | this one is an error do nothing */ + if (tree->isError || + (tree->left && tree->left->isError) || + (tree->right && tree->right->isError)) { + fprintf(outfile,"ERROR_NODE(%p)\n",tree); + } + + + /* print the line */ + /* if not block & function */ + if (tree->type == EX_OP && + (tree->opval.op != FUNCTION && + tree->opval.op != BLOCK && + tree->opval.op != NULLOP)) { + } + + if (tree->opval.op == FUNCTION) { + int arg=0; + value *args=FUNC_ARGS(tree->left->opval.val->type); + fprintf(outfile,"FUNCTION (%s=%p) type (", + tree->left->opval.val->name, tree); + printTypeChain (tree->left->opval.val->type->next,outfile); + fprintf(outfile,") args ("); + do { + if (arg) { + fprintf (outfile, ", "); + } + printTypeChain (args ? args->type : NULL, outfile); + arg++; + args= args ? args->next : NULL; + } while (args); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent); + ast_print(tree->right,outfile,indent); + return ; + } + if (tree->opval.op == BLOCK) { + symbol *decls = tree->values.sym; + INDENT(indent,outfile); + fprintf(outfile,"{\n"); + while (decls) { + INDENT(indent+2,outfile); + fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (", + decls->name, decls); + printTypeChain(decls->type,outfile); + fprintf(outfile,")\n"); + + decls = decls->next; + } + ast_print(tree->right,outfile,indent+2); + INDENT(indent,outfile); + fprintf(outfile,"}\n"); + return; + } + if (tree->opval.op == NULLOP) { + ast_print(tree->left,outfile,indent); + ast_print(tree->right,outfile,indent); + return ; + } + INDENT(indent,outfile); + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* leaf has been reached */ + /*----------------------------*/ + /* if this is of type value */ + /* just get the type */ + if (tree->type == EX_VALUE) { + + if (IS_LITERAL (tree->opval.val->etype)) { + fprintf(outfile,"CONSTANT (%p) value = ", tree); + if (SPEC_USIGN (tree->opval.val->etype)) + fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val)); + else + fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val)); + fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val), + floatFromVal(tree->opval.val)); + } else if (tree->opval.val->sym) { + /* if the undefined flag is set then give error message */ + if (tree->opval.val->sym->undefined) { + fprintf(outfile,"UNDEFINED SYMBOL "); + } else { + fprintf(outfile,"SYMBOL "); + } + fprintf(outfile,"(%s=%p @ %p)", + tree->opval.val->sym->name, tree, tree->opval.val->sym); + } + if (tree->ftype) { + fprintf(outfile," type ("); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + } else { + fprintf(outfile,"\n"); + } + return ; + } + + /* if type link for the case of cast */ + if (tree->type == EX_LINK) { + fprintf(outfile,"TYPENODE (%p) type = (",tree); + printTypeChain(tree->opval.lnk,outfile); + fprintf(outfile,")\n"); + return ; + } + + + /* depending on type of operator do */ + + switch (tree->opval.op) { + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* array node */ + /*----------------------------*/ + case '[': + fprintf(outfile,"ARRAY_OP (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* struct/union */ + /*----------------------------*/ + case '.': + fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* struct/union pointer */ + /*----------------------------*/ + case PTR_OP: + fprintf(outfile,"PTR_ACCESS (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* ++/-- operation */ + /*----------------------------*/ + case INC_OP: + if (tree->left) + fprintf(outfile,"post-"); + else + fprintf(outfile,"pre-"); + fprintf(outfile,"INC_OP (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); /* postincrement case */ + ast_print(tree->right,outfile,indent+2); /* preincrement case */ + return ; + + case DEC_OP: + if (tree->left) + fprintf(outfile,"post-"); + else + fprintf(outfile,"pre-"); + fprintf(outfile,"DEC_OP (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); /* postdecrement case */ + ast_print(tree->right,outfile,indent+2); /* predecrement case */ + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* bitwise and */ + /*----------------------------*/ + case '&': + if (tree->right) { + fprintf(outfile,"& (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + } else { + fprintf(outfile,"ADDRESS_OF (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + } + return ; + /*----------------------------*/ + /* bitwise or */ + /*----------------------------*/ + case '|': + fprintf(outfile,"OR (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* bitwise xor */ + /*----------------------------*/ + case '^': + fprintf(outfile,"XOR (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* division */ + /*----------------------------*/ + case '/': + fprintf(outfile,"DIV (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* modulus */ + /*----------------------------*/ + case '%': + fprintf(outfile,"MOD (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* address dereference */ + /*----------------------------*/ + case '*': /* can be unary : if right is null then unary operation */ + if (!tree->right) { + fprintf(outfile,"DEREF (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + return ; + } + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* multiplication */ + /*----------------------------*/ + fprintf(outfile,"MULT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* unary '+' operator */ + /*----------------------------*/ + case '+': + /* if unary plus */ + if (!tree->right) { + fprintf(outfile,"UPLUS (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + } else { + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* addition */ + /*----------------------------*/ + fprintf(outfile,"ADD (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + } + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* unary '-' */ + /*----------------------------*/ + case '-': /* can be unary */ + if (!tree->right) { + fprintf(outfile,"UMINUS (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + } else { + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* subtraction */ + /*----------------------------*/ + fprintf(outfile,"SUB (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + } + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* complement */ + /*----------------------------*/ + case '~': + fprintf(outfile,"COMPL (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* not */ + /*----------------------------*/ + case '!': + fprintf(outfile,"NOT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* shift */ + /*----------------------------*/ + case RRC: + fprintf(outfile,"RRC (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + return ; + + case RLC: + fprintf(outfile,"RLC (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + return ; + case SWAP: + fprintf(outfile,"SWAP (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + return ; + case GETHBIT: + fprintf(outfile,"GETHBIT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + return ; + case GETABIT: + fprintf(outfile,"GETABIT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case GETBYTE: + fprintf(outfile,"GETBYTE (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case GETWORD: + fprintf(outfile,"GETWORD (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case LEFT_OP: + fprintf(outfile,"LEFT_SHIFT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case RIGHT_OP: + fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* casting */ + /*----------------------------*/ + case CAST: /* change the type */ + fprintf(outfile,"CAST (%p) from type (",tree); + printTypeChain(tree->right->ftype,outfile); + fprintf(outfile,") to type ("); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->right,outfile,indent+2); + return ; + + case AND_OP: + fprintf(outfile,"ANDAND (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case OR_OP: + fprintf(outfile,"OROR (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* comparison operators */ + /*----------------------------*/ + case '>': + fprintf(outfile,"GT(>) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case '<': + fprintf(outfile,"LT(<) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case LE_OP: + fprintf(outfile,"LE(<=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case GE_OP: + fprintf(outfile,"GE(>=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case EQ_OP: + fprintf(outfile,"EQ(==) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + case NE_OP: + fprintf(outfile,"NE(!=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* sizeof */ + /*----------------------------*/ + case SIZEOF: /* evaluate wihout code generation */ + fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype))); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* conditional operator '?' */ + /*----------------------------*/ + case '?': + fprintf(outfile,"QUEST(?) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + + case ':': + fprintf(outfile,"COLON(:) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* assignment operators */ + /*----------------------------*/ + case MUL_ASSIGN: + fprintf(outfile,"MULASS(*=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + case DIV_ASSIGN: + fprintf(outfile,"DIVASS(/=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + case AND_ASSIGN: + fprintf(outfile,"ANDASS(&=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + case OR_ASSIGN: + fprintf(outfile,"ORASS(|=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + case XOR_ASSIGN: + fprintf(outfile,"XORASS(^=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + case RIGHT_ASSIGN: + fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + case LEFT_ASSIGN: + fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* -= operator */ + /*----------------------------*/ + case SUB_ASSIGN: + fprintf(outfile,"SUBASS(-=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* += operator */ + /*----------------------------*/ + case ADD_ASSIGN: + fprintf(outfile,"ADDASS(+=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* straight assignemnt */ + /*----------------------------*/ + case '=': + fprintf(outfile,"ASSIGN(=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* comma operator */ + /*----------------------------*/ + case ',': + fprintf(outfile,"COMMA(,) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* function call */ + /*----------------------------*/ + case CALL: + case PCALL: + fprintf(outfile,"CALL (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent+2); + return; + case PARAM: + fprintf(outfile,"PARMS\n"); + ast_print(tree->left,outfile,indent+2); + if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) { + ast_print(tree->right,outfile,indent+2); + } + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* return statement */ + /*----------------------------*/ + case RETURN: + fprintf(outfile,"RETURN (%p) type (",tree); + if (tree->right) { + printTypeChain(tree->right->ftype,outfile); + } + fprintf(outfile,")\n"); + ast_print(tree->right,outfile,indent+2); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* label statement */ + /*----------------------------*/ + case LABEL : + fprintf(outfile,"LABEL (%p)\n",tree); + ast_print(tree->left,outfile,indent+2); + ast_print(tree->right,outfile,indent); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* switch statement */ + /*----------------------------*/ + case SWITCH: + { + value *val; + fprintf(outfile,"SWITCH (%p) ",tree); + ast_print(tree->left,outfile,0); + for (val = tree->values.switchVals.swVals; val ; val = val->next) { + INDENT(indent+2,outfile); + fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n", + (int) floatFromVal(val), + tree->values.switchVals.swNum, + (int) floatFromVal(val)); + } + ast_print(tree->right,outfile,indent); + } + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* ifx Statement */ + /*----------------------------*/ + case IFX: + fprintf(outfile,"IF (%p) \n",tree); + ast_print(tree->left,outfile,indent+2); + if (tree->trueLabel) { + INDENT(indent+2,outfile); + fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name); + } + if (tree->falseLabel) { + INDENT(indent+2,outfile); + fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name); + } + ast_print(tree->right,outfile,indent+2); + return ; + /*----------------------------*/ + /* goto Statement */ + /*----------------------------*/ + case GOTO: + fprintf(outfile,"GOTO (%p) \n",tree); + ast_print(tree->left,outfile,indent+2); + fprintf(outfile,"\n"); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* for Statement */ + /*----------------------------*/ + case FOR: + fprintf(outfile,"FOR (%p) \n",tree); + if (AST_FOR( tree, initExpr)) { + INDENT(indent+2,outfile); + fprintf(outfile,"INIT EXPR "); + ast_print(AST_FOR(tree, initExpr),outfile,indent+2); + } + if (AST_FOR( tree, condExpr)) { + INDENT(indent+2,outfile); + fprintf(outfile,"COND EXPR "); + ast_print(AST_FOR(tree, condExpr),outfile,indent+2); + } + if (AST_FOR( tree, loopExpr)) { + INDENT(indent+2,outfile); + fprintf(outfile,"LOOP EXPR "); + ast_print(AST_FOR(tree, loopExpr),outfile,indent+2); + } + fprintf(outfile,"FOR LOOP BODY \n"); + ast_print(tree->left,outfile,indent+2); + return ; + case CRITICAL: + fprintf(outfile,"CRITICAL (%p) \n",tree); + ast_print(tree->left,outfile,indent+2); + default: + return ; + } } void PA(ast *t) { - ast_print(t,stdout,0); + ast_print(t,stdout,0); } @@ -6095,12 +6763,12 @@ void PA(ast *t) int astErrors(ast *t) { int errors=0; - + if (t) { if (t->isError) errors++; - + if (t->type == EX_VALUE && t->opval.val->sym && t->opval.val->sym->undefined) @@ -6109,6 +6777,6 @@ int astErrors(ast *t) errors += astErrors(t->left); errors += astErrors(t->right); } - + return errors; }