X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=4901b9a75c5323e0509646edb40d1aea2129bccc;hb=0659e7e1fdcce8778173cef767fc0e086e9fae0a;hp=869752b3955dfb9a774bd5952a2ded9cc0d322f7;hpb=831cf141d641f01012775e08b4c29448b2033a3d;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index 869752b3..4901b9a7 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -168,7 +168,7 @@ newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel) } /*-----------------------------------------------------------------*/ -/* copyAstValues - copies value portion of ast if needed */ +/* copyAstValues - copies value portion of ast if needed */ /*-----------------------------------------------------------------*/ void copyAstValues (ast * dest, ast * src) @@ -540,7 +540,6 @@ resolveSymbols (ast * tree) werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, tree->falseLabel->name); } - } /* if this is a label resolve it from the labelTab */ @@ -548,7 +547,6 @@ resolveSymbols (ast * tree) tree->opval.val->sym && tree->opval.val->sym->islbl) { - symbol *csym = findSym (LabelTab, tree->opval.val->sym, tree->opval.val->sym->name); @@ -566,7 +564,6 @@ resolveSymbols (ast * tree) tree->opval.val->sym && !tree->opval.val->sym->implicit) { - symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym); /* if found in the symbol table & they are not the same */ @@ -582,7 +579,6 @@ resolveSymbols (ast * tree) /* is an integer in data space */ if (!csym && !tree->opval.val->sym->implicit) { - /* if this is a function name then */ /* mark it as returning an int */ if (tree->funcName) @@ -961,10 +957,13 @@ createIvalType (ast * sym, sym_link * type, initList * ilist) ast *iExpr; /* if initList is deep */ - if (ilist->type == INIT_DEEP) + if (ilist && ilist->type == INIT_DEEP) ilist = ilist->init.deep; - iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE); + if (ilist) + iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE); + else + iExpr = newAst_VALUE (valueFromLit (0)); return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE); } @@ -978,28 +977,31 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue) ast *lAst; symbol *sflds; initList *iloop; + sym_link * etype = getSpec (type); sflds = SPEC_STRUCT (type)->fields; - if (ilist->type != INIT_DEEP) + if (ilist && ilist->type != INIT_DEEP) { werror (E_INIT_STRUCT, ""); return NULL; } - iloop = ilist->init.deep; + iloop = ilist ? ilist->init.deep : NULL; for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) { /* if we have come to end */ - if (!iloop) - break; + if (!iloop && (!AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype))) + { + break; + } + sflds->implicit = 1; lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds))); lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE); rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast, rootValue)), RESULT_TYPE_NONE); - } if (iloop) @@ -1015,7 +1017,6 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue) return rast; } - /*-----------------------------------------------------------------*/ /* createIvalArray - generates code for array initialization */ /*-----------------------------------------------------------------*/ @@ -1026,6 +1027,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue) initList *iloop; int lcnt = 0, size = 0; literalList *literalL; + sym_link * etype = getSpec (type); /* take care of the special case */ /* array of characters can be init */ @@ -1033,23 +1035,29 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue) if (IS_CHAR (type->next)) if ((rast = createIvalCharPtr (sym, type, - decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE), + decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE), rootValue))) return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE); - /* not the special case */ - if (ilist->type != INIT_DEEP) - { + /* not the special case */ + if (ilist && ilist->type != INIT_DEEP) + { werror (E_INIT_STRUCT, ""); return NULL; - } + } - iloop = ilist->init.deep; + iloop = ilist ? ilist->init.deep : NULL; lcnt = DCL_ELEM (type); - if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL)) - { + if (!iloop && + (!lcnt || !DCL_ELEM (type) || !AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype))) + { + return NULL; + } + + if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL, lcnt)) + { ast *aSym; aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE); @@ -1059,45 +1067,48 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue) // Make sure size is set to length of initializer list. while (iloop) - { + { size++; iloop = iloop->next; - } + } if (lcnt && size > lcnt) - { + { // Array size was specified, and we have more initializers than needed. werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef, - W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name); - } - } + W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name); + } + } else - { + { for (;;) - { + { ast *aSym; + if (!iloop && + (!lcnt || !DCL_ELEM (type) || !AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype))) + { + break; + } + aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++)))); aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE); rast = createIval (aSym, type->next, iloop, rast, rootValue); + lcnt--; iloop = (iloop ? iloop->next : NULL); - if (!iloop) - { - break; - } /* no of elements given and we */ /* have generated for all of them */ - if (!--lcnt) - { + if (!lcnt && iloop) + { // is this a better way? at least it won't crash char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : ""; werrorfl (iloop->filename, iloop->lineno, W_EXCESS_INITIALIZERS, "array", name); break; - } - } - } + } + } + } /* if we have not been given a size */ if (!DCL_ELEM (type)) @@ -1130,6 +1141,29 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal) return newNode ('=', sym, iexpr); /* left side is an array so we have to assign each element */ + if (!iexpr) + { + /* for each character generate an assignment */ + /* to the array element */ + unsigned int i = 0; + unsigned int symsize = getSize (type); + + if (!AST_SYMBOL (rootVal)->islocal || SPEC_STAT (getSpec (type))) + return NULL; + + for (i=0; ietype) || SPEC_SCLS (iexpr->etype) == S_CODE) && IS_ARRAY (iexpr->ftype)) @@ -1193,7 +1227,7 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal) ast *iexpr; /* if deep then */ - if (ilist->type == INIT_DEEP) + if (ilist && ilist->type == INIT_DEEP) ilist = ilist->init.deep; iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE); @@ -1214,7 +1248,7 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootVa { ast *rast = NULL; - if (!ilist) + if (!ilist && (!AST_SYMBOL (rootValue)->islocal || SPEC_STAT (getSpec (type)))) return NULL; /* if structure then */ @@ -1242,7 +1276,8 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootVa /*-----------------------------------------------------------------*/ /* initAggregates - initialises aggregate variables with initv */ /*-----------------------------------------------------------------*/ -ast * initAggregates (symbol * sym, initList * ival, ast * wid) { +ast * initAggregates (symbol * sym, initList * ival, ast * wid) +{ ast *newAst = newAst_VALUE (symbolVal (sym)); return createIval (newAst, sym->type, ival, wid, newAst); } @@ -1261,7 +1296,6 @@ gatherAutoInit (symbol * autoChain) inInitMode = 1; for (sym = autoChain; sym; sym = sym->next) { - /* resolve the symbols in the ival */ if (sym->ival) resolveIvalSym (sym->ival, sym->type); @@ -1322,28 +1356,33 @@ gatherAutoInit (symbol * autoChain) /* if there is an initial value */ if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE) { - initList *ilist=sym->ival; + initList *ilist = sym->ival; - while (ilist->type == INIT_DEEP) { - ilist = ilist->init.deep; - } + while (ilist->type == INIT_DEEP) + { + ilist = ilist->init.deep; + } /* update lineno for error msg */ 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); - } else { - if (getNelements(sym->type, sym->ival)>1) { - werrorfl (sym->fileDef, sym->lineDef, - W_EXCESS_INITIALIZERS, "scalar", - sym->name); + if (IS_AGGREGATE (sym->type)) + { + work = initAggregates (sym, sym->ival, NULL); + } + else + { + if (getNelements(sym->type, sym->ival)>1) + { + werrorfl (sym->fileDef, sym->lineDef, + W_EXCESS_INITIALIZERS, "scalar", + sym->name); + } + work = newNode ('=', newAst_VALUE (symbolVal (sym)), + list2expr (sym->ival)); } - work = newNode ('=', newAst_VALUE (symbolVal (sym)), - list2expr (sym->ival)); - } // just to be sure setAstFileLine (work, sym->fileDef, sym->lineDef); @@ -1460,7 +1499,6 @@ processBlockVars (ast * tree, int *stack, int action) return tree; } - /*-------------------------------------------------------------*/ /* constExprTree - returns TRUE if this tree is a constant */ /* expression */ @@ -2487,10 +2525,8 @@ decorateType (ast * tree, RESULT_TYPE resultType) /* just get the type */ if (tree->type == EX_VALUE) { - if (IS_LITERAL (tree->opval.val->etype)) { - /* if this is a character array then declare it */ if (IS_ARRAY (tree->opval.val->type)) tree->opval.val = stringToSymbol (tree->opval.val); @@ -5968,8 +6004,6 @@ DEFSETFUNC (resetParmKey) return 1; } - - /*------------------------------------------------------------------*/ /* fixupInlineLabel - change a label in an inlined function so that */ /* it is always unique no matter how many times */ @@ -5984,7 +6018,6 @@ fixupInlineLabel (symbol * sym) strcpy (sym->name, name); } - /*------------------------------------------------------------------*/ /* copyAstLoc - copy location information (file, line, block, etc.) */ /* from one ast node to another */ @@ -5997,10 +6030,8 @@ copyAstLoc (ast * dest, ast * src) 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 */ @@ -6009,13 +6040,13 @@ copyAstLoc (ast * dest, ast * src) static void fixupInline (ast * tree, int level) { - tree->block = currBlockno; + int savedBlockno = currBlockno; if (IS_AST_OP (tree) && (tree->opval.op == BLOCK)) { symbol * decls; - currBlockno++; + currBlockno = ++blockNo; level++; /* Add any declared variables back into the symbol table */ @@ -6030,6 +6061,7 @@ fixupInline (ast * tree, int level) } tree->level = level; + tree->block = currBlockno; /* Update symbols */ if (IS_AST_VALUE (tree) && @@ -6083,10 +6115,10 @@ fixupInline (ast * tree, int level) tree->right = gotoTree; } - /* Update any children */ - if (tree->left) + /* Update any children */ + if (tree->left) fixupInline (tree->left, level); - if (tree->right) + if (tree->right) fixupInline (tree->right, level); if (IS_AST_OP (tree) && (tree->opval.op == LABEL)) @@ -6098,10 +6130,10 @@ fixupInline (ast * tree, int level) addSym (LabelTab, label, label->name, label->level, 0, 0); } - if (IS_AST_OP (tree) && (tree->opval.op == BLOCK)) { level--; + currBlockno = savedBlockno; } } @@ -6138,7 +6170,6 @@ inlineAddDecl (symbol * sym, ast * block, int addSymTab) } } - /*-----------------------------------------------------------------*/ /* inlineTempVar - create a temporary variable for inlining */ /*-----------------------------------------------------------------*/ @@ -6163,7 +6194,6 @@ inlineTempVar (sym_link * type, int level) return sym; } - /*-----------------------------------------------------------------*/ /* inlineFindParmRecurse - recursive function for inlineFindParm */ /*-----------------------------------------------------------------*/ @@ -6190,7 +6220,6 @@ inlineFindParmRecurse (ast * parms, int *index) return NULL; } - /*-----------------------------------------------------------------*/ /* inlineFindParm - search an ast tree of parameters to find one */ /* at a particular index (0=first parameter). */ @@ -6202,33 +6231,6 @@ 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 */ @@ -6288,19 +6290,13 @@ expandInlineFuncs (ast * tree, ast * block) /* 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; */ + /* type1 temparg1 = argument1; */ /* ... */ - /* typen tempargn; */ - /* temparg1 = argument1; */ - /* ... */ - /* tempargn = argumentn; */ + /* typen tempargn = argumentn; */ /* { //inlinetree2 block */ - /* type1 param1; */ - /* ... */ - /* typen paramn; */ - /* param1 = temparg1; */ + /* type1 param1 = temparg1; */ /* ... */ - /* paramn = tempargn; */ + /* typen paramn = tempargn; */ /* inline_function_code; */ /* retlab: */ /* } */ @@ -6326,6 +6322,7 @@ expandInlineFuncs (ast * tree, ast * block) assigntree = newNode ('=', newAst_VALUE (symbolVal (temparg)), passedarg); + assigntree->initMode=1; // tell that assignment is initializer inlinetree->right = newNode (NULLOP, assigntree, inlinetree->right); @@ -6337,11 +6334,11 @@ expandInlineFuncs (ast * tree, ast * block) assigntree = newNode ('=', newAst_VALUE (symbolVal (parm)), newAst_VALUE (symbolVal (temparg))); + assigntree->initMode=1; // tell that assignment is initializer inlinetree2->right = newNode (NULLOP, assigntree, inlinetree2->right); - args = args->next; argIndex++; } @@ -6381,7 +6378,6 @@ expandInlineFuncs (ast * tree, ast * block) fixupInline (inlinetree, inlinetree->level); inlineState.count++; } - } /* Recursively continue to search for functions to inline. */ @@ -6397,7 +6393,6 @@ expandInlineFuncs (ast * tree, ast * block) } } - /*-----------------------------------------------------------------*/ /* createFunction - This is the key node that calls the iCode for */ /* generating the code for a function. Note code */ @@ -6412,7 +6407,6 @@ 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); @@ -6469,10 +6463,7 @@ createFunction (symbol * name, ast * body) reentrant++; inlineState.count = 0; - savedBlockno = currBlockno; - currBlockno = inlineFindMaxBlockno (body, 0); expandInlineFuncs (body, NULL); - currBlockno = savedBlockno; if (FUNC_ISINLINE (name->type)) name->funcTree = copyAst (body); @@ -6556,7 +6547,8 @@ skipall: /* we are done freeup memory & cleanup */ noLineno--; - if (port->reset_labelKey) labelKey = 1; + if (port->reset_labelKey) + labelKey = 1; name->key = 0; FUNC_HASBODY(name->type) = 1; addSet (&operKeyReset, name);