X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=94a1c5a24e80b7a06776e58d3b7fa8a5bf978e0c;hb=930f2bac961bfc56a967734091da6da5c2317960;hp=04d0a63b5af9b25a106cc10e90d296a640991b97;hpb=fe9b00fb61dc71f48cb6416e608b5b6882bbc35f;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index 04d0a63b..94a1c5a2 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -31,6 +31,11 @@ set *astList = NULL; set *operKeyReset = NULL; ast *staticAutos = NULL; int labelKey = 1; +static struct { + int count; /* number of inline functions inserted */ + symbol * retsym; /* variable for inlined function return value */ + symbol * retlab; /* label ending inlined function (virtual return) */ +} inlineState; #define LRVAL(x) x->left->rvalue #define RRVAL(x) x->right->rvalue @@ -63,7 +68,7 @@ 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; +struct dbuf_s *codeOutBuf; int ptt (ast * tree) { @@ -79,13 +84,12 @@ static ast * newAst_ (unsigned type) { ast *ex; - static int oldLineno = 0; ex = Safe_alloc ( sizeof (ast)); ex->type = type; - ex->lineno = (noLineno ? oldLineno : mylineno); - ex->filename = currFname; + ex->lineno = (noLineno ? 0 : lexLineno); + ex->filename = lexFilename; ex->level = NestLevel; ex->block = currBlockno; ex->initMode = inInitMode; @@ -218,6 +222,7 @@ copyAst (ast * src) dest = Safe_alloc ( sizeof (ast)); dest->type = src->type; + dest->filename = src->filename; dest->lineno = src->lineno; dest->level = src->level; dest->funcName = src->funcName; @@ -345,7 +350,7 @@ static ast *replaceAstWithTemporary(ast **treeptr) tempvar = newNode('=', newAst_VALUE(symbolVal(sym)), *treeptr); *treeptr = newAst_VALUE(symbolVal(sym)); - + addSymChain(&sym); return tempvar; @@ -375,17 +380,20 @@ ast * createRMW (ast *target, unsigned op, ast *operand) 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) { + 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?] */ + both values [WIML: Why not transform a[b] to *(a+b) in parser?] */ if (hasSEFcalls(target->left)) - tempvar1 = replaceAstWithTemporary(&(target->left)); + tempvar1 = replaceAstWithTemporary(&(target->left)); if (hasSEFcalls(target->right)) - tempvar2 = replaceAstWithTemporary(&(target->right)); + tempvar2 = replaceAstWithTemporary(&(target->right)); + } else if ((target->opval.op == INC_OP) || (target->opval.op == DEC_OP)) { + /* illegal pre/post-increment/decrement */ + werrorfl (target->filename, target->lineno, E_LVALUE_REQUIRED, "="); } else { /* we would have to handle '.', but it is not generated any more */ wassertl(target->opval.op != '.', "obsolete opcode in tree"); @@ -404,7 +412,7 @@ ast * createRMW (ast *target, unsigned op, ast *operand) result = newNode(',', tempvar1, result); return result; - + } /*-----------------------------------------------------------------*/ @@ -561,7 +569,7 @@ resolveSymbols (ast * tree) symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym); - /* if found in the symbol table & they r not the same */ + /* if found in the symbol table & they are not the same */ if (csym && tree->opval.val->sym != csym) { tree->opval.val->sym = csym; @@ -570,8 +578,8 @@ resolveSymbols (ast * tree) } /* if not found in the symbol table */ - /* mark it as undefined assume it is */ - /* an integer in data space */ + /* mark it as undefined & assume it */ + /* is an integer in data space */ if (!csym && !tree->opval.val->sym->implicit) { @@ -608,17 +616,18 @@ resolveChildren: return tree; } -/*-----------------------------------------------------------------*/ -/* setAstLineno - walks a ast tree & sets the line number */ -/*-----------------------------------------------------------------*/ -int setAstLineno (ast * tree, int lineno) +/*------------------------------------------------------------------------*/ +/* setAstFileLine - walks a ast tree & sets the file name and line number */ +/*------------------------------------------------------------------------*/ +int setAstFileLine (ast * tree, char *filename, int lineno) { if (!tree) return 0; + tree->filename = filename; tree->lineno = lineno; - setAstLineno (tree->left, lineno); - setAstLineno (tree->right, lineno); + setAstFileLine (tree->left, filename, lineno); + setAstFileLine (tree->right, filename, lineno); return 0; } @@ -775,15 +784,15 @@ processParms (ast *func, 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 the function is being called via a pointer & */ + /* it has not been defined reentrant then we cannot */ + /* have parameters */ /* PIC16 port can... */ if (!TARGET_IS_PIC16) { if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto) { - werror (W_NONRENT_ARGS); + werror (E_NONRENT_ARGS); fatalError++; return 1; } @@ -845,8 +854,12 @@ processParms (ast *func, ast *newType = NULL; sym_link *ftype; - if (IS_CAST_OP (*actParm) - || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast)) + /* don't perform integer promotion of explicitly typecasted variable arguments + * if sdcc extensions are enabled */ + if (options.std_sdcc && + (IS_CAST_OP (*actParm) || + (IS_AST_SYM_VALUE (*actParm) && AST_VALUES (*actParm, removedCast)) || + (IS_AST_LIT_VALUE (*actParm) && AST_VALUES (*actParm, literalFromCast)))) { /* Parameter was explicitly typecast; don't touch it. */ return 0; @@ -878,6 +891,7 @@ processParms (ast *func, /* cast required; change this op to a cast. */ (*actParm)->decorated = 0; *actParm = newNode (CAST, newType, *actParm); + (*actParm)->filename = (*actParm)->right->filename; (*actParm)->lineno = (*actParm)->right->lineno; decorateType (*actParm, RESULT_TYPE_NONE); @@ -922,6 +936,18 @@ processParms (ast *func, (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype)); SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype); SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype); + + /* if the function is being called via a pointer & */ + /* this parameter is not passed in registers */ + /* then the function must be defined reentrant */ + if (IS_FUNCPTR (func->ftype) && !SPEC_REGPARM ((*actParm)->etype) && + !IFFUNC_ISREENT (functype) && !options.stackAuto) + { + werror (E_NONRENT_ARGS); + fatalError++; + return 1; + } + (*parmNumber)++; return 0; } @@ -976,10 +1002,14 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue) } - if (iloop) { - werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef, - W_EXCESS_INITIALIZERS, "struct", - sym->opval.val->sym->name); + if (iloop) + { + if (IS_AST_VALUE (sym)) + werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef, + W_EXCESS_INITIALIZERS, "struct", + sym->opval.val->sym->name); + else + werrorfl (sym->filename, sym->lineno, E_INIT_COUNT); } return rast; @@ -1037,11 +1067,8 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue) 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); + werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef, + W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name); } } else @@ -1065,9 +1092,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue) { // 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); + werrorfl (iloop->filename, iloop->lineno, W_EXCESS_INITIALIZERS, "array", name); break; } @@ -1104,8 +1129,7 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal) && IS_ARRAY (iexpr->ftype))) return newNode ('=', sym, iexpr); - /* left side is an array so we have to assign each */ - /* element */ + /* left side is an array so we have to assign each element */ if ((IS_LITERAL (iexpr->etype) || SPEC_SCLS (iexpr->etype) == S_CODE) && IS_ARRAY (iexpr->ftype)) @@ -1225,7 +1249,7 @@ ast * initAggregates (symbol * sym, initList * ival, ast * wid) { /*-----------------------------------------------------------------*/ /* gatherAutoInit - creates assignment expressions for initial */ -/* values */ +/* values */ /*-----------------------------------------------------------------*/ static ast * gatherAutoInit (symbol * autoChain) @@ -1284,7 +1308,7 @@ gatherAutoInit (symbol * autoChain) list2expr (sym->ival)); } - setAstLineno (work, sym->lineDef); + setAstFileLine (work, sym->fileDef, sym->lineDef); sym->ival = NULL; if (staticAutos) @@ -1305,8 +1329,9 @@ gatherAutoInit (symbol * autoChain) } /* update lineno for error msg */ - lineno=sym->lineDef; - setAstLineno (ilist->init.node, lineno); + filename = sym->fileDef; + lineno = sym->lineDef; + setAstFileLine (ilist->init.node, sym->fileDef, sym->lineDef); if (IS_AGGREGATE (sym->type)) { work = initAggregates (sym, sym->ival, NULL); @@ -1321,7 +1346,7 @@ gatherAutoInit (symbol * autoChain) } // just to be sure - setAstLineno (work, sym->lineDef); + setAstFileLine (work, sym->fileDef, sym->lineDef); sym->ival = NULL; if (init) @@ -1361,16 +1386,18 @@ stringToSymbol (value * val) 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)) { - // yes, this is old news. Don't publish it again. - sym->isstrlit++; // but raise the usage count - return symbolVal(sym); + 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)) + { + // yes, this is old news. Don't publish it again. + sym->isstrlit++; // but raise the usage count + return symbolVal (sym); + } } - } SNPRINTF (name, sizeof(name), "_str_%d", charLbl++); sym = newSymbol (name, 0); /* make it @ level 0 */ @@ -1533,13 +1560,13 @@ constExprValue (ast * cexpr, int check) 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) @@ -1553,7 +1580,7 @@ constExprValue (ast * cexpr, int check) { return cexpr->opval.val; } - return NULL; + return NULL; } /*-----------------------------------------------------------------*/ @@ -1572,7 +1599,6 @@ isLabelInAst (symbol * label, ast * tree) return isLabelInAst (label, tree->right) && isLabelInAst (label, tree->left); - } /*-----------------------------------------------------------------*/ @@ -1638,7 +1664,7 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, { *end = newNode ('+', condExpr->left->right, - newAst_VALUE (constVal ("1"))); + newAst_VALUE (constCharVal (1))); break; } return FALSE; @@ -1685,7 +1711,7 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, 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) + AST_ULONG_VALUE (loopExpr->right) != 1) return TRUE; } } @@ -2059,7 +2085,7 @@ replLoopSym (ast * body, symbol * sym) body->type = EX_OP; body->opval.op = '-'; body->left = newAst_VALUE (symbolVal (sym)); - body->right = newAst_VALUE (constVal ("1")); + body->right = newAst_VALUE (constCharVal (1)); } @@ -2099,7 +2125,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) end)); replLoopSym (loop->left, sym); - setAstLineno (rloop, init->lineno); + setAstFileLine (rloop, init->filename, init->lineno); rloop = newNode (NULLOP, newNode ('=', @@ -2111,7 +2137,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) newNode (NULLOP, newNode (SUB_ASSIGN, newAst_VALUE (symbolVal (sym)), - newAst_VALUE (constVal ("1"))), + newAst_VALUE (constCharVal (1))), rloop)))); rloop->lineno=init->lineno; @@ -2123,7 +2149,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) /* searchLitOp - search tree (*ops only) for an ast with literal */ /*-----------------------------------------------------------------*/ static ast * -searchLitOp (ast *tree, ast **parent, const unsigned char *ops) +searchLitOp (ast *tree, ast **parent, const char *ops) { ast *ret; @@ -2133,7 +2159,7 @@ searchLitOp (ast *tree, ast **parent, const unsigned char *ops) if (tree->right && IS_AST_OP(tree->right) && tree->right->right && - (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1])) + (tree->right->opval.op == (unsigned)ops[0] || tree->right->opval.op == (unsigned)ops[1])) { if (IS_LITERAL (RTYPE (tree->right)) != IS_LITERAL (LTYPE (tree->right))) @@ -2150,7 +2176,7 @@ searchLitOp (ast *tree, ast **parent, const unsigned char *ops) if (tree->left && IS_AST_OP(tree->left) && tree->left->right && - (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1])) + (tree->left->opval.op == (unsigned)ops[0] || tree->left->opval.op == (unsigned)ops[1])) { if (IS_LITERAL (RTYPE (tree->left)) != IS_LITERAL (LTYPE (tree->left))) @@ -2189,8 +2215,7 @@ getResultTypeFromType (sym_link *type) } if (IS_CHAR (type)) return RESULT_TYPE_CHAR; - if ( IS_INT (type) - && !IS_LONG (type)) + if (IS_INT (type) && !IS_LONG (type)) return RESULT_TYPE_INT; return RESULT_TYPE_OTHER; } @@ -2249,11 +2274,11 @@ addCast (ast *tree, RESULT_TYPE resultType, bool promote) newLink = newIntLink(); upCasted = TRUE; break; + case RESULT_TYPE_IFX: case RESULT_TYPE_OTHER: - if (!promote) - return tree; - /* return type is long, float: promote char to int */ - if (getSize (tree->etype) >= INTSIZE) + if (!promote || + /* return type is ifx, long, float: promote char to int */ + getSize (tree->etype) >= INTSIZE) return tree; newLink = newIntLink(); upCasted = TRUE; @@ -2263,6 +2288,7 @@ addCast (ast *tree, RESULT_TYPE resultType, bool promote) } tree->decorated = 0; tree = newNode (CAST, newAst_LINK (newLink), tree); + tree->filename = tree->right->filename; tree->lineno = tree->right->lineno; /* keep unsigned type during cast to smaller type, but not when promoting from char to int */ @@ -2281,17 +2307,22 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType) { case AND_OP: case OR_OP: - return resultType; + case '!': case '=': case '?': case ':': case '|': case '^': case '~': + case LEFT_OP: + case LABEL: + return resultType; case '*': case '+': case '-': - case LABEL: + if ((IS_AST_VALUE (tree->left) && !IS_INTEGRAL (tree->left->opval.val->etype)) || + (IS_AST_VALUE (tree->right) && !IS_INTEGRAL (tree->right->opval.val->etype))) + return RESULT_TYPE_NONE; return resultType; case '&': if (!tree->right) @@ -2362,7 +2393,7 @@ gatherImplicitVariables (ast * tree, ast * block) 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; @@ -2449,7 +2480,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ /* leaf has been reached */ /*----------------------------*/ - lineno=tree->lineno; + filename = tree->filename; + lineno = tree->lineno; /* if this is of type value */ /* just get the type */ if (tree->type == EX_VALUE) @@ -2472,7 +2504,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* 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); + werrorfl (tree->filename, tree->lineno, E_ID_UNDEF, tree->opval.val->sym->name); /* assume int */ TTYPE (tree) = TETYPE (tree) = tree->opval.val->type = tree->opval.val->sym->type = @@ -2535,7 +2567,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) upon tree->opval.op, if resultType can be propagated */ resultTypeProp = resultTypePropagate (tree, resultType); - if (tree->opval.op == '?') + if ((tree->opval.op == '?') && (resultTypeProp != RESULT_TYPE_BIT)) dtl = decorateType (tree->left, RESULT_TYPE_IFX); else dtl = decorateType (tree->left, resultTypeProp); @@ -2570,6 +2602,12 @@ decorateType (ast * tree, RESULT_TYPE resultType) there is resultType available */ dtr = tree->right; break; + case SIZEOF: + /* don't allocate string if it is a sizeof argument */ + ++noAlloc; + dtr = decorateType (tree->right, resultTypeProp); + --noAlloc; + break; default: dtr = decorateType (tree->right, resultTypeProp); break; @@ -2598,31 +2636,31 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* first check if this is a array or a pointer */ if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree)))) { - werror (E_NEED_ARRAY_PTR, "[]"); + werrorfl (tree->filename, tree->lineno, E_NEED_ARRAY_PTR, "[]"); goto errorTreeReturn; } /* check if the type of the idx */ if (!IS_INTEGRAL (RTYPE (tree))) { - werror (E_IDX_NOT_INT); + werrorfl (tree->filename, tree->lineno, E_IDX_NOT_INT); goto errorTreeReturn; } /* if the left is an rvalue then error */ if (LRVAL (tree)) { - werror (E_LVALUE_REQUIRED, "array access"); + werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "array access"); goto errorTreeReturn; } if (IS_LITERAL (RTYPE (tree))) { - int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree))); + int arrayIndex = (int) ulFromVal (valFromType (RETYPE (tree))); int arraySize = DCL_ELEM (LTYPE (tree)); if (arraySize && arrayIndex >= arraySize) { - werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize); + werrorfl (tree->filename, tree->lineno, W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize); } } @@ -2639,7 +2677,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* if this is not a structure */ if (!IS_STRUCT (LTYPE (tree))) { - werror (E_STRUCT_UNION, "."); + werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "."); goto errorTreeReturn; } TTYPE (tree) = structElemType (LTYPE (tree), @@ -2656,13 +2694,13 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* if not pointer to a structure */ if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree))) { - werror (E_PTR_REQD); + werrorfl (tree->filename, tree->lineno, E_PTR_REQD); goto errorTreeReturn; } if (!IS_STRUCT (LTYPE (tree)->next)) { - werror (E_STRUCT_UNION, "->"); + werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "->"); goto errorTreeReturn; } @@ -2752,7 +2790,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) 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 ? "++" : "--"); + werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--"); if (tree->right) RLVAL (tree) = 1; @@ -2772,8 +2810,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { - werror (E_BITWISE_OP); - werror (W_CONTINUE, "left & right types are "); + werrorfl (tree->filename, tree->lineno, E_BITWISE_OP); + werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2875,13 +2913,13 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* if bit field then error */ if (IS_BITVAR (tree->left->etype)) { - werror (E_ILLEGAL_ADDR, "address of bit variable"); + werrorfl (tree->filename, tree->lineno, 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"); + werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of register variable"); goto errorTreeReturn; } @@ -2893,13 +2931,13 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (IS_LITERAL(LTYPE(tree))) { - werror (E_ILLEGAL_ADDR, "address of literal"); + werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of literal"); goto errorTreeReturn; } if (LRVAL (tree)) { - werror (E_LVALUE_REQUIRED, "address of"); + werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "address of"); goto errorTreeReturn; } if (!LETYPE (tree)) @@ -2998,8 +3036,8 @@ 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 "); + werrorfl (tree->filename, tree->lineno, E_BITWISE_OP); + werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -3064,7 +3102,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) case '/': if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree))) { - werror (E_INVALID_OP, "divide"); + werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "divide"); goto errorTreeReturn; } /* if they are both literal then */ @@ -3093,7 +3131,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* rearrange the tree */ if (IS_LITERAL (RTYPE (tree)) /* avoid infinite loop */ - && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1) + && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 1) { ast *parent; ast *litTree = searchLitOp (tree, &parent, "/"); @@ -3106,9 +3144,10 @@ decorateType (ast * tree, RESULT_TYPE resultType) litTree->right = newNode ('*', litTree->right, copyAst (tree->right)); + litTree->right->filename = tree->filename; litTree->right->lineno = tree->lineno; - tree->right->opval.val = constVal ("1"); + tree->right->opval.val = constCharVal (1); decorateType (parent, resultType); } else @@ -3131,8 +3170,8 @@ 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 "); + werrorfl (tree->filename, tree->lineno, E_BITWISE_OP); + werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -3168,13 +3207,13 @@ decorateType (ast * tree, RESULT_TYPE resultType) { if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree))) { - werror (E_PTR_REQD); + werrorfl (tree->filename, tree->lineno, E_PTR_REQD); goto errorTreeReturn; } if (LRVAL (tree)) { - werror (E_LVALUE_REQUIRED, "pointer deref"); + werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref"); goto errorTreeReturn; } if (IS_ADDRESS_OF_OP(tree->left)) @@ -3223,7 +3262,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree))) { - werror (E_INVALID_OP, "multiplication"); + werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "multiplication"); goto errorTreeReturn; } @@ -3267,8 +3306,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) } LRVAL (tree) = RRVAL (tree) = 1; - tree->left = addCast (tree->left, resultType, FALSE); - tree->right = addCast (tree->right, resultType, FALSE); + tree->left = addCast (tree->left, resultTypeProp, FALSE); + tree->right = addCast (tree->right, resultTypeProp, FALSE); TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), @@ -3287,7 +3326,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) { if (!IS_ARITHMETIC (LTYPE (tree))) { - werror (E_UNARY_OP, '+'); + werrorfl (tree->filename, tree->lineno, E_UNARY_OP, '+'); goto errorTreeReturn; } @@ -3315,21 +3354,21 @@ decorateType (ast * tree, RESULT_TYPE resultType) if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) && (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)))) { - werror (E_PTR_PLUS_PTR); + werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR); goto errorTreeReturn; } if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree))) { - werror (E_PLUS_INVALID, "+"); + werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+"); goto errorTreeReturn; } if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree))) { - werror (E_PLUS_INVALID, "+"); + werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+"); goto errorTreeReturn; } /* if they are both literal then */ @@ -3337,8 +3376,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) 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->left = addCast (tree->left, resultTypeProp, TRUE); + tree->right = addCast (tree->right, resultTypeProp, TRUE); tree->opval.val = valPlus (valFromType (LETYPE (tree)), valFromType (RETYPE (tree))); tree->right = tree->left = NULL; @@ -3408,8 +3447,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) LTYPE (tree)); else { - tree->left = addCast (tree->left, resultType, TRUE); - tree->right = addCast (tree->right, resultType, TRUE); + tree->left = addCast (tree->left, resultTypeProp, TRUE); + tree->right = addCast (tree->right, resultTypeProp, TRUE); TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), @@ -3430,7 +3469,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (!IS_ARITHMETIC (LTYPE (tree))) { - werror (E_UNARY_OP, tree->opval.op); + werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op); goto errorTreeReturn; } @@ -3443,7 +3482,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; return tree; } - tree->left = addCast (tree->left, resultType, TRUE); + tree->left = addCast (tree->left, resultTypeProp, TRUE); TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), NULL, @@ -3462,7 +3501,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) IS_ARRAY (LTYPE (tree)) || IS_ARITHMETIC (LTYPE (tree)))) { - werror (E_PLUS_INVALID, "-"); + werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-"); goto errorTreeReturn; } @@ -3470,7 +3509,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) IS_ARRAY (RTYPE (tree)) || IS_ARITHMETIC (RTYPE (tree)))) { - werror (E_PLUS_INVALID, "-"); + werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-"); goto errorTreeReturn; } @@ -3478,7 +3517,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) || IS_INTEGRAL (RTYPE (tree)))) { - werror (E_PLUS_INVALID, "-"); + werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-"); goto errorTreeReturn; } @@ -3487,8 +3526,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) 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->left = addCast (tree->left, resultTypeProp, TRUE); + tree->right = addCast (tree->right, resultTypeProp, TRUE); tree->opval.val = valMinus (valFromType (LETYPE (tree)), valFromType (RETYPE (tree))); tree->right = tree->left = NULL; @@ -3502,7 +3541,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) { tree->type = EX_VALUE; tree->left = tree->right = NULL; - tree->opval.val = constVal ("0"); + tree->opval.val = constCharVal (0); TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; return tree; } @@ -3520,8 +3559,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) LTYPE (tree)); else { - tree->left = addCast (tree->left, resultType, TRUE); - tree->right = addCast (tree->right, resultType, TRUE); + tree->left = addCast (tree->left, resultTypeProp, TRUE); + tree->right = addCast (tree->right, resultTypeProp, TRUE); TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), @@ -3537,7 +3576,7 @@ 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) + && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 0) { ast *litTree, *litParent; litTree = searchLitOp (tree, &litParent, "+-"); @@ -3591,7 +3630,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* can be only integral type */ if (!IS_INTEGRAL (LTYPE (tree))) { - werror (E_UNARY_OP, tree->opval.op); + werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op); goto errorTreeReturn; } @@ -3602,7 +3641,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->opval.val = valComplement (valFromType (LETYPE (tree))); tree->left = NULL; TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - return addCast (tree, resultType, TRUE); + return addCast (tree, resultTypeProp, TRUE); } if (resultType == RESULT_TYPE_BIT && @@ -3613,14 +3652,14 @@ decorateType (ast * tree, RESULT_TYPE resultType) bit -> int -> ~int -> bit uchar -> int -> ~int -> bit */ - werror(W_COMPLEMENT); + werrorfl (tree->filename, tree->lineno, W_COMPLEMENT); /* optimize bit-result, even if we optimize a buggy source */ tree->type = EX_VALUE; - tree->opval.val = constVal ("1"); + tree->opval.val = constCharVal (1); } else - tree->left = addCast (tree->left, resultType, TRUE); + tree->left = addCast (tree->left, resultTypeProp, TRUE); LRVAL (tree) = 1; COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); return tree; @@ -3635,19 +3674,25 @@ decorateType (ast * tree, RESULT_TYPE resultType) !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree))) { - werror (E_UNARY_OP, tree->opval.op); + werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op); goto errorTreeReturn; } /* if left is another '!' */ - if (tree->left->opval.op == '!') + if (IS_AST_NOT_OPER (tree->left)) { + if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT)) + { + /* replace double '!!X' by 'X' */ + return tree->left->left; + } /* 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"))); + newAst_VALUE (constCharVal (1)), + newAst_VALUE (constCharVal (0))); + tree->right->filename = tree->filename; tree->right->lineno = tree->lineno; tree->decorated = 0; return decorateType (tree, resultType); @@ -3694,8 +3739,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) 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 "); + werrorfl (tree->filename, tree->lineno, E_SHIFT_OP_INVALID); + werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -3705,7 +3750,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* make smaller type only if it's a LEFT_OP */ if (tree->opval.op == LEFT_OP) - tree->left = addCast (tree->left, resultType, TRUE); + tree->left = addCast (tree->left, resultTypeProp, TRUE); /* if they are both literal then */ /* rewrite the tree */ @@ -3759,18 +3804,17 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* 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)))) >= + ((TYPE_TARGET_ULONG) ulFromVal (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, + werrorfl (tree->filename, tree->lineno, W_SHIFT_CHANGED, (tree->opval.op == LEFT_OP ? "left" : "right")); tree->type = EX_VALUE; tree->left = tree->right = NULL; - tree->opval.val = constVal ("0"); + tree->opval.val = constCharVal (0); TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; return tree; } @@ -3786,7 +3830,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* cannot cast to an aggregate type */ if (IS_AGGREGATE (LTYPE (tree))) { - werror (E_CAST_ILLEGAL); + werrorfl (tree->filename, tree->lineno, E_CAST_ILLEGAL); goto errorTreeReturn; } @@ -3794,10 +3838,14 @@ decorateType (ast * tree, RESULT_TYPE resultType) changePointer(LTYPE(tree)); checkTypeSanity(LETYPE(tree), "(cast)"); - /* if 'from' and 'to' are the same remove the superfluous cast, */ - /* this helps other optimizations */ + + /* if 'from' and 'to' are the same remove the superfluous cast, + * this helps other optimizations */ if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1) { + /* mark that the explicit cast has been removed, + * for proper processing (no integer promotion) of explicitly typecasted variable arguments */ + tree->right->values.removedCast = 1; return tree->right; } @@ -3831,9 +3879,9 @@ decorateType (ast * tree, RESULT_TYPE resultType) 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 */ { + ((int) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ { sym_link *rest = LTYPE(tree)->next; - werror(W_LITERAL_GENERIC); + werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC); TTYPE(tree) = newLink(DECLARATOR); DCL_TYPE(TTYPE(tree)) = FPOINTER; TTYPE(tree)->next = rest; @@ -3854,7 +3902,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) 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, + werrorfl (tree->filename, tree->lineno, W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag, SPEC_STRUCT(LETYPE(tree))->tag); } #endif @@ -3866,7 +3914,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) unsigned int gptype = 0; unsigned int addr = SPEC_ADDR (sym->etype); - if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE) + if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE) + || TARGET_IS_PIC16) ) { switch (SPEC_SCLS (sym->etype)) { @@ -3885,6 +3934,9 @@ decorateType (ast * tree, RESULT_TYPE resultType) break; default: gptype = 0; + + if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED)) + gptype = GPTYPE_NEAR; } addr |= gptype << (8*(GPTRSIZE - 1)); } @@ -3963,6 +4015,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) allocGlobal (sym); newTree->left = newAst_VALUE(symbolVal(sym)); + newTree->left->filename = tree->filename; newTree->left->lineno = tree->lineno; LTYPE (newTree) = sym->type; LETYPE (newTree) = sym->etype; @@ -4004,7 +4057,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) !IS_ARRAY (LTYPE (tree)) && !IS_INTEGRAL (LTYPE (tree))) { - werror (E_COMPARE_OP); + werrorfl (tree->filename, tree->lineno, E_COMPARE_OP); goto errorTreeReturn; } @@ -4012,7 +4065,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) !IS_ARRAY (RTYPE (tree)) && !IS_INTEGRAL (RTYPE (tree))) { - werror (E_COMPARE_OP); + werrorfl (tree->filename, tree->lineno, E_COMPARE_OP); goto errorTreeReturn; } /* if they are both literal then */ @@ -4062,7 +4115,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) } if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { - werror (E_COMPARE_OP); + werrorfl (tree->filename, tree->lineno, E_COMPARE_OP); fprintf (stderr, "comparing type "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, "to type "); @@ -4079,7 +4132,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { - werror (E_COMPARE_OP); + werrorfl (tree->filename, tree->lineno, E_COMPARE_OP); fprintf (stderr, "comparing type "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, "to type "); @@ -4106,11 +4159,9 @@ decorateType (ast * tree, RESULT_TYPE resultType) case CCR_ALWAYS_TRUE: case CCR_ALWAYS_FALSE: if (!options.lessPedantic) - werror (W_COMP_RANGE, + werrorfl (tree->filename, tree->lineno, W_COMP_RANGE, ccr_result == CCR_ALWAYS_TRUE ? "true" : "false"); - return decorateType (newAst_VALUE (constVal ( - ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")), - resultType); + return decorateType (newAst_VALUE (constCharVal ((unsigned char)(ccr_result == CCR_ALWAYS_TRUE))), resultType); case CCR_OK: default: break; @@ -4121,9 +4172,9 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (tree->opval.op == '>' && SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && - ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) + ((int) ulFromVal (valFromType (RETYPE (tree)))) == 0) { - if (resultType == RESULT_TYPE_IFX) + if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT)) { /* the parent is an ifx: */ /* if (unsigned value) */ @@ -4133,9 +4184,11 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* (unsigned value) ? 1 : 0 */ tree->opval.op = '?'; tree->right = newNode (':', - newAst_VALUE (constVal ("1")), + newAst_VALUE (constCharVal (1)), tree->right); /* val 0 */ + tree->right->filename = tree->filename; tree->right->lineno = tree->lineno; + tree->right->left->filename = tree->filename; tree->right->left->lineno = tree->lineno; tree->decorated = 0; return decorateType (tree, resultType); @@ -4145,7 +4198,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (IS_LITERAL(RTYPE(tree)) && floatFromVal (valFromType (RETYPE (tree))) == 0 && tree->opval.op == EQ_OP && - resultType == RESULT_TYPE_IFX) + (resultType == RESULT_TYPE_IFX || resultType == RESULT_TYPE_BIT)) { tree->opval.op = '!'; tree->right = NULL; @@ -4180,27 +4233,27 @@ decorateType (ast * tree, RESULT_TYPE resultType) 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) + (int) ulFromVal (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) + (int) ulFromVal (valFromType (LETYPE (tree))) < 128) { SPEC_USIGN (LETYPE (tree)) = 0; } else { - werror (W_CMP_SU_CHAR); + werrorfl (tree->filename, tree->lineno, 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) = newBoolLink (); + TTYPE (tree) = TETYPE (tree) = (resultType == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); /* condition transformations */ { @@ -4240,6 +4293,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->opval.op = transformedOp; tree->decorated = 0; tree = newNode ('!', tree, NULL); + tree->filename = tree->left->filename; tree->lineno = tree->left->lineno; return decorateType (tree, resultType); } @@ -4255,6 +4309,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* 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); @@ -4264,6 +4319,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->right = tree->left = NULL; TETYPE (tree) = getSpec (TTYPE (tree) = tree->opval.val->type); + return tree; /*------------------------------------------------------------------*/ @@ -4352,21 +4408,55 @@ decorateType (ast * tree, RESULT_TYPE resultType) case '?': /* 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 */ + + /* If already known then replace the tree : optimizer will do it + but faster to do it here. If done before decorating tree->right + this can save generating unused const strings. */ if (IS_LITERAL (LTYPE (tree))) { - if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) + if (((int) ulFromVal (valFromType (LETYPE (tree)))) != 0) return decorateType (tree->right->left, resultTypeProp); else return decorateType (tree->right->right, resultTypeProp); } - else + + tree->right = decorateType (tree->right, resultTypeProp); + + if (IS_AST_LIT_VALUE (tree->right->left) && IS_AST_LIT_VALUE (tree->right->right) && + ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))) { - tree->right = decorateType (tree->right, resultTypeProp); - TTYPE (tree) = RTYPE (tree); - TETYPE (tree) = getSpec (TTYPE (tree)); + double valTrue = AST_FLOAT_VALUE (tree->right->left); + double valFalse = AST_FLOAT_VALUE (tree->right->right); + + if ((valTrue != 0) && (valFalse == 0)) + { + /* assign cond to result */ + tree->left->decorated = 0; + return decorateType (tree->left, resultTypeProp); + } + else if ((valTrue == 0) && (valFalse != 0)) + { + /* assign !cond to result */ + tree->opval.op = '!'; + tree->decorated = 0; + tree->right = NULL; + return decorateType (tree, resultTypeProp); + } + else + { + /* they have the same boolean value, make them equal */ + tree->right->left = tree->right->right; + } + } + + /* if they are equal then replace the tree */ + if (isAstEqual (tree->right->left, tree->right->right)) + { + return tree->right->left; } + + TTYPE (tree) = RTYPE (tree); + TETYPE (tree) = getSpec (TTYPE (tree)); return tree; case ':': @@ -4374,7 +4464,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) && (compareType (RTYPE (tree), LTYPE (tree)) == 0)) { - werror (E_TYPE_MISMATCH, "conditional operator", " "); + werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "conditional operator", " "); goto errorTreeReturn; } @@ -4395,18 +4485,18 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree))) { - werror (E_OPS_INTEGRAL); + werrorfl (tree->filename, tree->lineno, 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 ? "*=" : "/="); + werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/="); if (LRVAL (tree)) { - werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/="); + werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/="); goto errorTreeReturn; } LLVAL (tree) = 1; @@ -4422,18 +4512,18 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { - werror (E_OPS_INTEGRAL); + werrorfl (tree->filename, tree->lineno, 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 <<="); + werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "&= or |= or ^= or >>= or <<="); if (LRVAL (tree)) { - werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<="); + werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<="); goto errorTreeReturn; } LLVAL (tree) = 1; @@ -4448,14 +4538,14 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (!(IS_PTR (LTYPE (tree)) || IS_ARITHMETIC (LTYPE (tree)))) { - werror (E_PLUS_INVALID, "-="); + werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-="); goto errorTreeReturn; } if (!(IS_PTR (RTYPE (tree)) || IS_ARITHMETIC (RTYPE (tree)))) { - werror (E_PLUS_INVALID, "-="); + werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-="); goto errorTreeReturn; } RRVAL (tree) = 1; @@ -4466,11 +4556,11 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->opval.op)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) - werror (E_CODE_WRITE, "-="); + werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "-="); if (LRVAL (tree)) { - werror (E_LVALUE_REQUIRED, "-="); + werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "-="); goto errorTreeReturn; } LLVAL (tree) = 1; @@ -4486,19 +4576,19 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* if both pointers then problem */ if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree))) { - werror (E_PTR_PLUS_PTR); + werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR); goto errorTreeReturn; } if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree))) { - werror (E_PLUS_INVALID, "+="); + werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+="); goto errorTreeReturn; } if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree))) { - werror (E_PLUS_INVALID, "+="); + werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+="); goto errorTreeReturn; } RRVAL (tree) = 1; @@ -4509,11 +4599,11 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->opval.op)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) - werror (E_CODE_WRITE, "+="); + werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "+="); if (LRVAL (tree)) { - werror (E_LVALUE_REQUIRED, "+="); + werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "+="); goto errorTreeReturn; } @@ -4531,14 +4621,14 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* cannot be an aggregate */ if (IS_AGGREGATE (LTYPE (tree))) { - werror (E_AGGR_ASSIGN); + werrorfl (tree->filename, tree->lineno, E_AGGR_ASSIGN); goto errorTreeReturn; } /* they should either match or be castable */ if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { - werror (E_TYPE_MISMATCH, "assignment", " "); + werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "assignment", " "); printFromToType(RTYPE(tree),LTYPE(tree)); } @@ -4546,7 +4636,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) then report error */ if (IS_VOID (LTYPE (tree))) { - werror (E_CAST_ZERO); + werrorfl (tree->filename, tree->lineno, E_CAST_ZERO); printFromToType(RTYPE(tree), LTYPE(tree)); } @@ -4556,11 +4646,11 @@ decorateType (ast * tree, RESULT_TYPE resultType) LLVAL (tree) = 1; if (!tree->initMode ) { if (IS_CONSTANT(LTYPE(tree))) - werror (E_CODE_WRITE, "="); + werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "="); } if (LRVAL (tree)) { - werror (E_LVALUE_REQUIRED, "="); + werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "="); goto errorTreeReturn; } @@ -4667,7 +4757,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) if (!IS_VOID (currFunc->type->next) && tree->right == NULL) { - werror (W_VOID_FUNC, currFunc->name); + werrorfl (tree->filename, tree->lineno, W_VOID_FUNC, currFunc->name); goto errorTreeReturn; } @@ -4733,7 +4823,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->left), RESULT_TYPE_NONE); } case PARAM: - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + werrorfl (tree->filename, tree->lineno, E_INTERNAL_ERROR, __FILE__, __LINE__, "node PARAM shouldn't be processed here"); /* but in processParams() */ return tree; @@ -4794,6 +4884,7 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) /* 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); @@ -4897,6 +4988,7 @@ createBlock (symbol * decl, ast * body) ex->values.sym = decl; ex->level++; + ex->filename = NULL; ex->lineno = 0; return ex; } @@ -4933,6 +5025,7 @@ createLabel (symbol * label, ast * stmnt) label->islbl = 1; label->key = labelKey++; rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt); + rValue->filename = NULL; rValue->lineno = 0; return rValue; @@ -4978,8 +5071,8 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) { /* also order the cases according to value */ value *pval = NULL; - int cVal = (int) floatFromVal (caseVal->opval.val); - while (val && (int) floatFromVal (val) < cVal) + int cVal = (int) ulFromVal (caseVal->opval.val); + while (val && (int) ulFromVal (val) < cVal) { pval = val; val = val->next; @@ -4990,7 +5083,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) { pval->next = caseVal->opval.val; } - else if ((int) floatFromVal (val) == cVal) + else if ((int) ulFromVal (val) == cVal) { werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL, "case"); @@ -5017,9 +5110,10 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) SNPRINTF(caseLbl, sizeof(caseLbl), "_case_%d_%d", swStat->values.switchVals.swNum, - (int) floatFromVal (caseVal->opval.val)); + (int) ulFromVal (caseVal->opval.val)); rexpr = createLabel (newSymbol (caseLbl, 0), stmnt); + rexpr->filename = 0; rexpr->lineno = 0; return rexpr; } @@ -5143,11 +5237,13 @@ createDo (symbol * trueLabel, symbol * continueLabel, /* if the body does not exist then it is simple */ if (!doBody) { - condAst = backPatchLabels (condAst, continueLabel, NULL); + condAst = backPatchLabels (condAst, continueLabel, falseLabel); doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst) : newNode (IFX, createLabel (continueLabel, condAst), NULL)); doTree->trueLabel = continueLabel; doTree->falseLabel = NULL; + + doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL)); return doTree; } @@ -5253,10 +5349,12 @@ createWhile (symbol * trueLabel, symbol * continueLabel, /* put the continue label */ condExpr = backPatchLabels (condExpr, trueLabel, falseLabel); condExpr = createLabel (continueLabel, condExpr); + condExpr->filename = NULL; condExpr->lineno = 0; /* put the body label in front of the body */ whileBody = createLabel (trueLabel, whileBody); + whileBody->filename = NULL; whileBody->lineno = 0; /* put a jump to continue at the end of the body */ /* and put break label at the end of the body */ @@ -5319,7 +5417,7 @@ isBitAndPow2 (ast * tree) if (!IS_AST_LIT_VALUE (tree->right)) return -1; - return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right)); + return powof2 (AST_ULONG_VALUE (tree->right)); } /*-----------------------------------------------------------------*/ @@ -5328,14 +5426,14 @@ isBitAndPow2 (ast * tree) ast * optimizeGetHbit (ast * tree, RESULT_TYPE resultType) { - int i, j; + unsigned 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)) != + if ((AST_ULONG_VALUE (tree->right) != 1) || + ((i = AST_ULONG_VALUE (tree->left->right)) != (j = (getSize (TTYPE (expr)) * 8 - 1)))) expr = NULL; } @@ -5368,7 +5466,7 @@ optimizeGetAbit (ast * tree, RESULT_TYPE resultType) expr = isShiftRightLitVal_BitAndLitVal(tree); if (expr) { - if (AST_LIT_VALUE (tree->right) != 1) + if (AST_ULONG_VALUE (tree->right) != 1) expr = NULL; count = tree->left->right; } @@ -5406,9 +5504,9 @@ optimizeGetByte (ast * tree, RESULT_TYPE resultType) expr = isShiftRightLitVal_BitAndLitVal(tree); if (expr) { - i = (unsigned int) AST_LIT_VALUE (tree->left->right); + i = AST_ULONG_VALUE (tree->left->right); count = tree->left->right; - if (AST_LIT_VALUE (tree->right) != 0xFF) + if (AST_ULONG_VALUE (tree->right) != 0xFF) expr = NULL; } if (!expr && resultType == RESULT_TYPE_CHAR) @@ -5416,7 +5514,7 @@ optimizeGetByte (ast * tree, RESULT_TYPE resultType) /* 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); + i = AST_ULONG_VALUE (tree->right); count = tree->right; expr = tree->left; } @@ -5445,9 +5543,9 @@ optimizeGetWord (ast * tree, RESULT_TYPE resultType) expr = isShiftRightLitVal_BitAndLitVal(tree); if (expr) { - i = (unsigned int) AST_LIT_VALUE (tree->left->right); + i = AST_ULONG_VALUE (tree->left->right); count = tree->left->right; - if (AST_LIT_VALUE (tree->right) != 0xFFFF) + if (AST_ULONG_VALUE (tree->right) != 0xFFFF) expr = NULL; } if (!expr && resultType == RESULT_TYPE_INT) @@ -5455,7 +5553,7 @@ optimizeGetWord (ast * tree, RESULT_TYPE resultType) /* 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); + i = AST_ULONG_VALUE (tree->right); count = tree->right; expr = tree->left; } @@ -5511,10 +5609,10 @@ optimizeRRCRLC (ast * root) root->right->left)) goto tryNext0; - if (AST_LIT_VALUE (root->left->right) != 1) + if (AST_ULONG_VALUE (root->left->right) != 1) goto tryNext0; - if (AST_LIT_VALUE (root->right->right) != + if (AST_ULONG_VALUE (root->right->right) != (getSize (TTYPE (root->left->left)) * 8 - 1)) goto tryNext0; @@ -5546,10 +5644,10 @@ tryNext0: root->right->left)) goto tryNext1; - if (AST_LIT_VALUE (root->right->right) != 1) + if (AST_ULONG_VALUE (root->right->right) != 1) goto tryNext1; - if (AST_LIT_VALUE (root->left->right) != + if (AST_ULONG_VALUE (root->left->right) != (getSize (TTYPE (root->left->left)) * 8 - 1)) goto tryNext1; @@ -5582,10 +5680,10 @@ tryNext1: root->right->left)) goto tryNext2; - if (AST_LIT_VALUE (root->left->right) != 1) + if (AST_ULONG_VALUE (root->left->right) != 1) goto tryNext2; - if (AST_LIT_VALUE (root->right->right) != + if (AST_ULONG_VALUE (root->right->right) != (getSize (TTYPE (root->left->left)) * 8 - 1)) goto tryNext2; @@ -5617,10 +5715,10 @@ tryNext2: root->right->left)) return root; - if (AST_LIT_VALUE (root->right->right) != 1) + if (AST_ULONG_VALUE (root->right->right) != 1) return root; - if (AST_LIT_VALUE (root->left->right) != + if (AST_ULONG_VALUE (root->left->right) != (getSize (TTYPE (root->left->left)) * 8 - 1)) return root; @@ -5671,11 +5769,11 @@ optimizeSWAP (ast * root) root->right->left)) return root; - if (AST_LIT_VALUE (root->left->right) != + if (AST_ULONG_VALUE (root->left->right) != (getSize (TTYPE (root->left->left)) * 4)) return root; - if (AST_LIT_VALUE (root->right->right) != + if (AST_ULONG_VALUE (root->right->right) != (getSize (TTYPE (root->left->left)) * 4)) return root; @@ -5725,12 +5823,12 @@ optimizeCompare (ast * root) case '>': case '<': case NE_OP: - optExpr = newAst_VALUE (constVal ("0")); + optExpr = newAst_VALUE (constCharVal (0)); break; case GE_OP: case LE_OP: case EQ_OP: - optExpr = newAst_VALUE (constVal ("1")); + optExpr = newAst_VALUE (constCharVal (1)); break; } @@ -5744,8 +5842,8 @@ optimizeCompare (ast * root) root->right->opval.val : NULL); /* if left is a BITVAR in BITSPACE */ - /* and right is a LITERAL then opt- */ - /* imize else do nothing */ + /* and right is a LITERAL then */ + /* optimize else do nothing */ if (vleft && vright && IS_BITVAR (vleft->etype) && IN_BITSPACE (SPEC_OCLS (vleft->etype)) && @@ -5753,7 +5851,7 @@ optimizeCompare (ast * root) { /* if right side > 1 then comparison may never succeed */ - if ((litValue = (int) floatFromVal (vright)) > 1) + if ((litValue = (int) ulFromVal (vright)) > 1) { werror (W_BAD_COMPARE); goto noOptimize; @@ -5814,6 +5912,7 @@ optimizeCompare (ast * root) noOptimize: return root; } + /*-----------------------------------------------------------------*/ /* addSymToBlock : adds the symbol to the first block we find */ /*-----------------------------------------------------------------*/ @@ -5868,6 +5967,436 @@ DEFSETFUNC (resetParmKey) return 1; } + + +/*------------------------------------------------------------------*/ +/* fixupInlineLabel - change a label in an inlined function so that */ +/* it is always unique no matter how many times */ +/* the function is inlined. */ +/*------------------------------------------------------------------*/ +static void +fixupInlineLabel (symbol * sym) +{ + char name[SDCC_NAME_MAX + 1]; + + SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count); + strcpy (sym->name, name); +} + + +/*------------------------------------------------------------------*/ +/* copyAstLoc - copy location information (file, line, block, etc.) */ +/* from one ast node to another */ +/*------------------------------------------------------------------*/ +static void +copyAstLoc (ast * dest, ast * src) +{ + dest->filename = src->filename; + dest->lineno = src->lineno; + dest->level = src->level; + dest->block = src->block; + dest->seqPoint = src->seqPoint; + +} + + +/*-----------------------------------------------------------------*/ +/* fixupInline - perform various fixups on an inline function tree */ +/* to take into account that it is no longer a */ +/* stand-alone function. */ +/*-----------------------------------------------------------------*/ +static void +fixupInline (ast * tree, int level) +{ + tree->block = currBlockno; + + if (IS_AST_OP (tree) && (tree->opval.op == BLOCK)) + { + symbol * decls; + + currBlockno++; + level++; + + /* Add any declared variables back into the symbol table */ + decls = tree->values.sym; + while (decls) + { + decls->level = level; + decls->block = currBlockno; + addSym (SymbolTab, decls, decls->name, decls->level, decls->block, 0); + decls = decls->next; + } + } + + tree->level = level; + + /* Update symbols */ + if (IS_AST_VALUE (tree) && + tree->opval.val->sym) + { + symbol * sym = tree->opval.val->sym; + + sym->level = level; + sym->block = currBlockno; + + sym->reqv = NULL; + SYM_SPIL_LOC (sym) = NULL; + sym->key = 0; + + /* If the symbol is a label, we need to renumber it */ + if (sym->islbl) + fixupInlineLabel (sym); + } + + /* Update IFX target labels */ + if (tree->type == EX_OP && tree->opval.op == IFX) + { + if (tree->trueLabel) + fixupInlineLabel (tree->trueLabel); + if (tree->falseLabel) + fixupInlineLabel (tree->falseLabel); + } + + /* Replace RETURN with optional assignment and a GOTO to the end */ + /* of the inlined function */ + if (tree->type == EX_OP && tree->opval.op == RETURN) + { + ast * assignTree = NULL; + ast * gotoTree; + + if (inlineState.retsym && tree->right) + { + assignTree = newNode ('=', + newAst_VALUE (symbolVal (inlineState.retsym)), + tree->right); + copyAstLoc (assignTree, tree); + } + + gotoTree = newNode (GOTO, + newAst_VALUE (symbolVal (inlineState.retlab)), + NULL); + copyAstLoc (gotoTree, tree); + + tree->opval.op = NULLOP; + tree->left = assignTree; + tree->right = gotoTree; + } + + /* Update any children */ + if (tree->left) + fixupInline (tree->left, level); + if (tree->right) + fixupInline (tree->right, level); + + if (IS_AST_OP (tree) && (tree->opval.op == LABEL)) + { + symbol * label = tree->left->opval.val->sym; + + label->key = labelKey++; + /* Add this label back into the symbol table */ + addSym (LabelTab, label, label->name, label->level, 0, 0); + } + + + if (IS_AST_OP (tree) && (tree->opval.op == BLOCK)) + { + level--; + } +} + +/*-----------------------------------------------------------------*/ +/* inlineAddDecl - add a variable declaration to an ast block. It */ +/* is also added to the symbol table if addSymTab */ +/* is nonzero. */ +/*-----------------------------------------------------------------*/ +static void +inlineAddDecl (symbol * sym, ast * block, int addSymTab) +{ + sym->reqv = NULL; + SYM_SPIL_LOC (sym) = NULL; + sym->key = 0; + if (block != NULL) + { + symbol **decl = &(block->values.sym); + + sym->level = block->level; + sym->block = block->block; + + while (*decl) + { + if (strcmp ((*decl)->name, sym->name) == 0) + return; + decl = &( (*decl)->next ); + } + + *decl = sym; + + if (addSymTab) + addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 0); + + } +} + + +/*-----------------------------------------------------------------*/ +/* inlineTempVar - create a temporary variable for inlining */ +/*-----------------------------------------------------------------*/ +static symbol * +inlineTempVar (sym_link * type, int level) +{ + symbol * sym; + + sym = newSymbol (genSymName(level), level ); + sym->type = copyLinkChain (type); + sym->etype = getSpec(sym->type); + SPEC_SCLS (sym->etype) = S_AUTO; + SPEC_OCLS (sym->etype) = NULL; + SPEC_EXTR (sym->etype) = 0; + SPEC_STAT (sym->etype) = 0; + if IS_SPEC (sym->type) + SPEC_VOLATILE (sym->type) = 0; + else + DCL_PTR_VOLATILE (sym->type) = 0; + SPEC_ABSA (sym->etype) = 0; + + return sym; +} + + +/*-----------------------------------------------------------------*/ +/* inlineFindParmRecurse - recursive function for inlineFindParm */ +/*-----------------------------------------------------------------*/ +static ast * +inlineFindParmRecurse (ast * parms, int *index) +{ + if (!parms) + return NULL; + + if (parms->type == EX_OP && parms->opval.op == PARAM) + { + ast * p; + + p=inlineFindParmRecurse (parms->left, index); + if (p) + return p; + p=inlineFindParmRecurse (parms->right, index); + if (p) + return p; + } + if (!*index) + return parms; + (*index)--; + return NULL; +} + + +/*-----------------------------------------------------------------*/ +/* inlineFindParm - search an ast tree of parameters to find one */ +/* at a particular index (0=first parameter). */ +/* Returns NULL if not found. */ +/*-----------------------------------------------------------------*/ +static ast * +inlineFindParm (ast * parms, int index) +{ + return inlineFindParmRecurse (parms, &index); +} + +/*-----------------------------------------------------------------*/ +/* inlineFindMaxBlockno - find maximum block number in an ast tree */ +/*-----------------------------------------------------------------*/ +static int +inlineFindMaxBlockno (ast * tree, int maxBlockno) +{ + int tempBlockno; + + if (!tree) + return maxBlockno; + + tempBlockno = inlineFindMaxBlockno (tree->left, maxBlockno); + if (tempBlockno > maxBlockno) + maxBlockno = tempBlockno; + + tempBlockno = inlineFindMaxBlockno (tree->right, maxBlockno); + if (tempBlockno > maxBlockno) + maxBlockno = tempBlockno; + + if (tree->block > maxBlockno) + maxBlockno = tree->block; + return maxBlockno; +} + + + + +/*-----------------------------------------------------------------*/ +/* expandInlineFuncs - replace calls to inline functions with the */ +/* function itself */ +/*-----------------------------------------------------------------*/ +static void +expandInlineFuncs (ast * tree, ast * block) +{ + if (IS_AST_OP (tree) && (tree->opval.op == CALL) && tree->left + && IS_AST_VALUE (tree->left) && tree->left->opval.val->sym) + { + symbol * func = tree->left->opval.val->sym; + symbol * csym; + + /* The symbol is probably not bound yet, so find the real one */ + csym = findSymWithLevel (SymbolTab, func); + if (csym) + func = csym; + + /* Is this an inline function that we can inline? */ + if (IFFUNC_ISINLINE (func->type) && func->funcTree) + { + symbol * retsym = NULL; + symbol * retlab; + ast * inlinetree; + ast * inlinetree2; + ast * temptree; + value * args; + int argIndex; + + /* Generate a label for the inlined function to branch to */ + /* in case it contains a return statement */ + retlab = newSymbol (genSymName(tree->level+1), tree->level+1 ); + retlab->isitmp = 1; + retlab->islbl = 1; + inlineState.retlab = retlab; + + /* Build the subtree for the inlined function in the form: */ + /* { //inlinetree block */ + /* { //inlinetree2 block */ + /* inline_function_code; */ + /* retlab: */ + /* } */ + /* } */ + temptree = newNode (LABEL, newAst_VALUE (symbolVal (retlab)), NULL); + copyAstLoc (temptree, tree); + temptree = newNode (NULLOP, copyAst (func->funcTree), temptree); + copyAstLoc (temptree, tree); + temptree = newNode (BLOCK, NULL, temptree); + copyAstLoc (temptree, tree); + inlinetree2 = temptree; + inlinetree = newNode (BLOCK, NULL, inlinetree2); + copyAstLoc (inlinetree, tree); + + /* To pass parameters to the inlined function, we need some */ + /* intermediate variables. This avoids scoping problems */ + /* when the parameter declaration names are used differently */ + /* during the function call. For example, a function */ + /* declared as func(int x, int y) but called as func(y,x). */ + /* { //inlinetree block */ + /* type1 temparg1; */ + /* ... */ + /* typen tempargn; */ + /* temparg1 = argument1; */ + /* ... */ + /* tempargn = argumentn; */ + /* { //inlinetree2 block */ + /* type1 param1; */ + /* ... */ + /* typen paramn; */ + /* param1 = temparg1; */ + /* ... */ + /* paramn = tempargn; */ + /* inline_function_code; */ + /* retlab: */ + /* } */ + /* } */ + args = FUNC_ARGS (func->type); + argIndex = 0; + while (args) + { + symbol * temparg; + ast * assigntree; + symbol * parm; + ast * passedarg = inlineFindParm (tree->right, argIndex); + + if (!passedarg) + { + werror(E_TOO_FEW_PARMS); + break; + } + + temparg = inlineTempVar (args->sym->type, tree->level+1); + inlineAddDecl (temparg, inlinetree, FALSE); + + assigntree = newNode ('=', + newAst_VALUE (symbolVal (temparg)), + passedarg); + inlinetree->right = newNode (NULLOP, + assigntree, + inlinetree->right); + + parm = copySymbol (args->sym); + inlineAddDecl (parm, inlinetree2, FALSE); + parm->_isparm = 0; + + assigntree = newNode ('=', + newAst_VALUE (symbolVal (parm)), + newAst_VALUE (symbolVal (temparg))); + inlinetree2->right = newNode (NULLOP, + assigntree, + inlinetree2->right); + + + args = args->next; + argIndex++; + } + + /* Handle the return type */ + if (!IS_VOID (func->type->next)) + { + /* Create a temporary symbol to hold the return value and */ + /* join it with the inlined function using the comma */ + /* operator. The fixupInline function will take care of */ + /* changing return statements into assignments to retsym. */ + /* (parameter passing and return label omitted for clarity) */ + /* rettype retsym; */ + /* ... */ + /* {{inline_function_code}}, retsym */ + + retsym = inlineTempVar (func->type->next, tree->level); + inlineAddDecl (retsym, block, TRUE); + + tree->opval.op = ','; + tree->left = inlinetree; + tree->right = newAst_VALUE (symbolVal (retsym)); + } + else + { + tree->opval.op = NULLOP; + tree->left = NULL; + tree->right = inlinetree; + } + inlineState.retsym = retsym; + + /* Renumber the various internal counters on the inlined */ + /* function's tree nodes and symbols. Add the inlined */ + /* function's local variables to the appropriate scope(s). */ + /* Convert inlined return statements to an assignment to */ + /* retsym (if needed) and a goto retlab. */ + fixupInline (inlinetree, inlinetree->level); + inlineState.count++; + } + + } + + /* Recursively continue to search for functions to inline. */ + if (IS_AST_OP (tree)) + { + if (tree->opval.op == BLOCK) + block = tree; + + if (tree->left) + expandInlineFuncs (tree->left, block); + if (tree->right) + expandInlineFuncs (tree->right, block); + } +} + + /*-----------------------------------------------------------------*/ /* createFunction - This is the key node that calls the iCode for */ /* generating the code for a function. Note code */ @@ -5882,6 +6411,7 @@ createFunction (symbol * name, ast * body) int stack = 0; sym_link *fetype; iCode *piCode = NULL; + int savedBlockno; if (getenv("SDCC_DEBUG_FUNCTION_POINTERS")) fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name); @@ -5914,7 +6444,7 @@ createFunction (symbol * name, ast * body) addSymChain (&name); allocVariables (name); } - name->lastLine = mylineno; + name->lastLine = lexLineno; currFunc = name; /* set the stack pointer */ @@ -5937,6 +6467,15 @@ createFunction (symbol * name, ast * body) if (IFFUNC_ISREENT (name->type)) reentrant++; + inlineState.count = 0; + savedBlockno = currBlockno; + currBlockno = inlineFindMaxBlockno (body, 0); + expandInlineFuncs (body, NULL); + currBlockno = savedBlockno; + + if (FUNC_ISINLINE (name->type)) + name->funcTree = copyAst (body); + allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */ /* do processing for parameters that are passed in registers */ @@ -5967,23 +6506,30 @@ createFunction (symbol * name, ast * body) ex = newNode (FUNCTION, ex, body); ex->values.args = FUNC_ARGS(name->type); ex->decorated=1; - if (options.dump_tree) PA(ex); + if (options.dump_tree) + PA(ex); if (fatalError) - { - werror (E_FUNC_NO_CODE, name->name); - goto skipall; - } + goto skipall; + + /* Do not generate code for inline functions unless extern also. */ +#if 0 + if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype)) + goto skipall; +#else + /* Temporary hack: always generate code for static inline functions. */ + /* Ideally static inline functions should only be generated if needed. */ + if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype) && !IS_STATIC (fetype)) + goto skipall; +#endif /* create the node & generate intermediate code */ GcurMemmap = code; - codeOutFile = code->oFile; + codeOutBuf = &code->oBuf; piCode = iCodeFromAst (ex); + name->generated = 1; if (fatalError) - { - werror (E_FUNC_NO_CODE, name->name); - goto skipall; - } + goto skipall; eBBlockFromiCode (piCode); @@ -5991,7 +6537,7 @@ createFunction (symbol * name, ast * body) if (staticAutos) { GcurMemmap = statsg; - codeOutFile = statsg->oFile; + codeOutBuf = &statsg->oBuf; eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE))); staticAutos = NULL; } @@ -6028,7 +6574,7 @@ skipall: } -#define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); } +#define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); } /*-----------------------------------------------------------------*/ /* ast_print : prints the ast (for debugging purposes) */ /*-----------------------------------------------------------------*/ @@ -6036,722 +6582,720 @@ 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); + if (!tree) return ; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* 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 @ %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 ; - } + /* 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) ulFromVal(tree->opval.val)); + else + fprintf(outfile,"%d", (TYPE_TARGET_LONG) ulFromVal(tree->opval.val)); + fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) ulFromVal(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) ulFromVal(val), + tree->values.switchVals.swNum, + (int) ulFromVal(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); } - - /*-----------------------------------------------------------------*/ /* astErrors : returns non-zero if errors present in tree */ /*-----------------------------------------------------------------*/