}
/*-----------------------------------------------------------------*/
-/* copyAstValues - copies value portion of ast if needed */
+/* copyAstValues - copies value portion of ast if needed */
/*-----------------------------------------------------------------*/
void
copyAstValues (ast * dest, ast * src)
werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
tree->falseLabel->name);
}
-
}
/* if this is a label resolve it from the labelTab */
tree->opval.val->sym &&
tree->opval.val->sym->islbl)
{
-
symbol *csym = findSym (LabelTab, tree->opval.val->sym,
tree->opval.val->sym->name);
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 */
/* 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)
/* don't perform integer promotion of explicitly typecasted variable arguments
* if sdcc extensions are enabled */
- if (options.std_sdcc &&
+ 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))))
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);
}
/* createIvalStruct - generates initial value for structures */
/*-----------------------------------------------------------------*/
static ast *
-createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
+createIvalStruct (ast *sym, sym_link *type, initList *ilist, ast *rootValue)
{
ast *rast = NULL;
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))
+ for (sflds = SPEC_STRUCT (type)->fields; sflds; sflds = sflds->next)
{
/* if we have come to end */
- if (!iloop)
+ 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 (!IS_BITFIELD (sflds->type) || !SPEC_BUNNAMED (sflds->etype))
+ {
+ 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);
+ iloop = iloop ? iloop->next : NULL;
+ }
}
if (iloop)
sym->opval.val->sym->name);
else
werrorfl (sym->filename, sym->lineno, E_INIT_COUNT);
- }
+ }
return rast;
}
-
/*-----------------------------------------------------------------*/
/* createIvalArray - generates code for array initialization */
/*-----------------------------------------------------------------*/
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 */
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);
// 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))
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; i < symsize; ++i)
+ {
+ rast = newNode (NULLOP,
+ rast,
+ newNode ('=',
+ newNode ('[', sym,
+ newAst_VALUE (valueFromLit ((float) i))),
+ newAst_VALUE (valueFromLit (0))));
+ }
+
+ return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
+ }
+
if ((IS_LITERAL (iexpr->etype) ||
SPEC_SCLS (iexpr->etype) == S_CODE)
&& IS_ARRAY (iexpr->ftype))
unsigned int symsize = getSize (type);
size = getSize (iexpr->ftype);
- if (symsize && size>symsize)
+ if (symsize && size > symsize)
{
- if (size>(symsize+1))
+ if (size > symsize)
{
char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
size = symsize;
}
- for (i=0;i<size;i++)
+ for (i = 0; i < size; i++)
{
rast = newNode (NULLOP,
rast,
newNode ('=',
newNode ('[', sym,
newAst_VALUE (valueFromLit ((float) i))),
- newAst_VALUE (valueFromLit (*s))));
- s++;
+ newAst_VALUE (valueFromLit (*s++))));
}
// now WE don't need iexpr's symbol anymore
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);
{
ast *rast = NULL;
- if (!ilist)
+ if (!ilist && (!AST_SYMBOL (rootValue)->islocal || SPEC_STAT (getSpec (type))))
return NULL;
/* if structure then */
/*-----------------------------------------------------------------*/
/* 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);
}
inInitMode = 1;
for (sym = autoChain; sym; sym = sym->next)
{
-
/* resolve the symbols in the ival */
if (sym->ival)
resolveIvalSym (sym->ival, sym->type);
/* 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);
return tree;
}
-
/*-------------------------------------------------------------*/
/* constExprTree - returns TRUE if this tree is a constant */
/* expression */
return 1;
}
-
-
/*------------------------------------------------------------------*/
/* fixupInlineLabel - change a label in an inlined function so that */
/* it is always unique no matter how many times */
strcpy (sym->name, name);
}
-
/*------------------------------------------------------------------*/
/* copyAstLoc - copy location information (file, line, block, etc.) */
/* from one ast node to another */
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 */
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 */
}
tree->level = level;
+ tree->block = currBlockno;
/* Update symbols */
if (IS_AST_VALUE (tree) &&
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))
addSym (LabelTab, label, label->name, label->level, 0, 0);
}
-
if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
{
level--;
+ currBlockno = savedBlockno;
}
}
}
}
-
/*-----------------------------------------------------------------*/
/* inlineTempVar - create a temporary variable for inlining */
/*-----------------------------------------------------------------*/
return sym;
}
-
/*-----------------------------------------------------------------*/
/* inlineFindParmRecurse - recursive function for inlineFindParm */
/*-----------------------------------------------------------------*/
return NULL;
}
-
/*-----------------------------------------------------------------*/
/* inlineFindParm - search an ast tree of parameters to find one */
/* at a particular index (0=first parameter). */
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 */
}
}
-
/*-----------------------------------------------------------------*/
/* createFunction - This is the key node that calls the iCode for */
/* generating the code for a function. Note code */
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);
reentrant++;
inlineState.count = 0;
- savedBlockno = currBlockno;
- currBlockno = inlineFindMaxBlockno (body, 0);
expandInlineFuncs (body, NULL);
- currBlockno = savedBlockno;
if (FUNC_ISINLINE (name->type))
name->funcTree = copyAst (body);
/* 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);