}
/*-----------------------------------------------------------------*/
-/* 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))))
(*actParm)->left = newAst_LINK (defParm->type);
(*actParm)->right = pTree;
(*actParm)->decorated = 0; /* force typechecking */
- decorateType (*actParm, resultType);
+ decorateType (*actParm, IS_GENPTR (defParm->type) ? RESULT_TYPE_GPTR : resultType);
}
/* make a copy and change the regparm type to the defined parm */
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 */
/* 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);
changePointer(LTYPE(tree));
checkTypeSanity(LETYPE(tree), "(cast)");
-
/* if 'from' and 'to' are the same remove the superfluous cast,
* this helps other optimizations */
if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
#if 0
/* if the right is a literal replace the tree */
- if (IS_LITERAL (RETYPE (tree))) {
- if (!IS_PTR (LTYPE (tree))) {
- tree->type = EX_VALUE;
- tree->opval.val =
- valCastLiteral (LTYPE (tree),
- floatFromVal (valFromType (RETYPE (tree))));
- tree->left = NULL;
- tree->right = NULL;
- TTYPE (tree) = tree->opval.val->type;
- tree->values.literalFromCast = 1;
- } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
- ((int) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
- sym_link *rest = LTYPE(tree)->next;
- werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
- TTYPE(tree) = newLink(DECLARATOR);
- DCL_TYPE(TTYPE(tree)) = FPOINTER;
- TTYPE(tree)->next = rest;
- tree->left->opval.lnk = TTYPE(tree);
- LRVAL (tree) = 1;
- } else {
- TTYPE (tree) = LTYPE (tree);
- LRVAL (tree) = 1;
- }
- } else {
+ if (IS_LITERAL (RETYPE (tree)))
+ {
+ if (!IS_PTR (LTYPE (tree)))
+ {
+ tree->type = EX_VALUE;
+ tree->opval.val =
+ valCastLiteral (LTYPE (tree),
+ floatFromVal (valFromType (RETYPE (tree))));
+ tree->left = NULL;
+ tree->right = NULL;
+ TTYPE (tree) = tree->opval.val->type;
+ tree->values.literalFromCast = 1;
+ }
+ else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
+ ((int) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */
+ {
+ sym_link *rest = LTYPE(tree)->next;
+ werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
+ TTYPE(tree) = newLink(DECLARATOR);
+ DCL_TYPE(TTYPE(tree)) = FPOINTER;
+ TTYPE(tree)->next = rest;
+ tree->left->opval.lnk = TTYPE(tree);
+ LRVAL (tree) = 1;
+ }
+ else
+ {
TTYPE (tree) = LTYPE (tree);
LRVAL (tree) = 1;
- }
+ }
+ }
+ else
+ {
+ TTYPE (tree) = LTYPE (tree);
+ LRVAL (tree) = 1;
+ }
#else
#if 0 // this is already checked, now this could be explicit
/* if pointer to struct then check names */
#endif
if (IS_ADDRESS_OF_OP(tree->right)
&& IS_AST_SYM_VALUE (tree->right->left)
- && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
-
- symbol * sym = AST_SYMBOL (tree->right->left);
- unsigned int gptype = 0;
- unsigned int addr = SPEC_ADDR (sym->etype);
+ && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype))
+ {
+ symbol * sym = AST_SYMBOL (tree->right->left);
+ unsigned int gptype = 0;
+ unsigned int addr = SPEC_ADDR (sym->etype);
- if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE)
- || TARGET_IS_PIC16) )
- {
- switch (SPEC_SCLS (sym->etype))
- {
- case S_CODE:
- gptype = GPTYPE_CODE;
- break;
- case S_XDATA:
- gptype = GPTYPE_FAR;
- break;
- case S_DATA:
- case S_IDATA:
- gptype = GPTYPE_NEAR;
- break;
- case S_PDATA:
- gptype = GPTYPE_XSTACK;
- break;
- default:
- gptype = 0;
+ if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE) || TARGET_IS_PIC16) )
+ {
+ switch (SPEC_SCLS (sym->etype))
+ {
+ case S_CODE:
+ gptype = GPTYPE_CODE;
+ break;
+ case S_XDATA:
+ gptype = GPTYPE_FAR;
+ break;
+ case S_DATA:
+ case S_IDATA:
+ gptype = GPTYPE_NEAR;
+ break;
+ case S_PDATA:
+ gptype = GPTYPE_XSTACK;
+ break;
+ default:
+ gptype = 0;
- if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
- gptype = GPTYPE_NEAR;
- }
- addr |= gptype << (8*(GPTRSIZE - 1));
- }
+ if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
+ gptype = GPTYPE_NEAR;
+ }
+ addr |= gptype << (8*(GPTRSIZE - 1));
+ }
- tree->type = EX_VALUE;
- tree->opval.val =
- valCastLiteral (LTYPE (tree), addr);
- TTYPE (tree) = tree->opval.val->type;
- TETYPE (tree) = getSpec (TTYPE (tree));
- tree->left = NULL;
- tree->right = NULL;
- tree->values.literalFromCast = 1;
- return tree;
- }
+ tree->type = EX_VALUE;
+ tree->opval.val = valCastLiteral (LTYPE (tree), addr);
+ TTYPE (tree) = tree->opval.val->type;
+ TETYPE (tree) = getSpec (TTYPE (tree));
+ tree->left = NULL;
+ tree->right = NULL;
+ tree->values.literalFromCast = 1;
+ return tree;
+ }
/* handle offsetof macro: */
/* #define offsetof(TYPE, MEMBER) \ */
&& tree->right->left->opval.op == PTR_OP
&& IS_AST_OP (tree->right->left->left)
&& tree->right->left->left->opval.op == CAST
- && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
-
- symbol *element = getStructElement (
- SPEC_STRUCT (LETYPE(tree->right->left)),
- AST_SYMBOL(tree->right->left->right)
- );
-
- if (element) {
- tree->type = EX_VALUE;
- tree->opval.val = valCastLiteral (
- LTYPE (tree),
- element->offset
- + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
+ && IS_AST_LIT_VALUE(tree->right->left->left->right))
+ {
+ symbol *element = getStructElement (
+ SPEC_STRUCT (LETYPE(tree->right->left)),
+ AST_SYMBOL(tree->right->left->right)
);
- TTYPE (tree) = tree->opval.val->type;
- TETYPE (tree) = getSpec (TTYPE (tree));
- tree->left = NULL;
- tree->right = NULL;
- return tree;
- }
+ if (element)
+ {
+ tree->type = EX_VALUE;
+ tree->opval.val = valCastLiteral (
+ LTYPE (tree),
+ element->offset
+ + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
+ );
+
+ TTYPE (tree) = tree->opval.val->type;
+ TETYPE (tree) = getSpec (TTYPE (tree));
+ tree->left = NULL;
+ tree->right = NULL;
+ return tree;
+ }
}
/* if the right is a literal replace the tree */
- if (IS_LITERAL (RETYPE (tree))) {
- #if 0
- if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
- /* rewrite (type *)litaddr
- as &temp
- and define type at litaddr temp
- (but only if type's storage class is not generic)
- */
- ast *newTree = newNode ('&', NULL, NULL);
- symbol *sym;
-
- TTYPE (newTree) = LTYPE (tree);
- TETYPE (newTree) = getSpec(LTYPE (tree));
-
- /* define a global symbol at the casted address*/
- sym = newSymbol(genSymName (0), 0);
- sym->type = LTYPE (tree)->next;
- if (!sym->type)
- sym->type = newLink (V_VOID);
- sym->etype = getSpec(sym->type);
- SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
- sym->lineDef = tree->lineno;
- sym->cdef = 1;
- sym->isref = 1;
- SPEC_STAT (sym->etype) = 1;
- SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
- SPEC_ABSA(sym->etype) = 1;
- addSym (SymbolTab, sym, sym->name, 0, 0, 0);
- 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;
- LLVAL (newTree) = 1;
- LRVAL (newTree) = 0;
- TLVAL (newTree) = 1;
- return newTree;
- }
- #endif
- if (!IS_PTR (LTYPE (tree))) {
- tree->type = EX_VALUE;
- tree->opval.val =
- valCastLiteral (LTYPE (tree),
- floatFromVal (valFromType (RTYPE (tree))));
- TTYPE (tree) = tree->opval.val->type;
- tree->left = NULL;
- tree->right = NULL;
- tree->values.literalFromCast = 1;
- TETYPE (tree) = getSpec (TTYPE (tree));
- return tree;
+ if (IS_LITERAL (RETYPE (tree)))
+ {
+ #if 0
+ if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) )
+ {
+ /* rewrite (type *)litaddr
+ as &temp
+ and define type at litaddr temp
+ (but only if type's storage class is not generic)
+ */
+ ast *newTree = newNode ('&', NULL, NULL);
+ symbol *sym;
+
+ TTYPE (newTree) = LTYPE (tree);
+ TETYPE (newTree) = getSpec(LTYPE (tree));
+
+ /* define a global symbol at the casted address*/
+ sym = newSymbol(genSymName (0), 0);
+ sym->type = LTYPE (tree)->next;
+ if (!sym->type)
+ sym->type = newLink (V_VOID);
+ sym->etype = getSpec(sym->type);
+ SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
+ sym->lineDef = tree->lineno;
+ sym->cdef = 1;
+ sym->isref = 1;
+ SPEC_STAT (sym->etype) = 1;
+ SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
+ SPEC_ABSA(sym->etype) = 1;
+ addSym (SymbolTab, sym, sym->name, 0, 0, 0);
+ 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;
+ LLVAL (newTree) = 1;
+ LRVAL (newTree) = 0;
+ TLVAL (newTree) = 1;
+ return newTree;
+ }
+ #endif
+ if (!IS_PTR (LTYPE (tree)))
+ {
+ tree->type = EX_VALUE;
+ tree->opval.val =
+ valCastLiteral (LTYPE (tree), floatFromVal (valFromType (RTYPE (tree))));
+ TTYPE (tree) = tree->opval.val->type;
+ tree->left = NULL;
+ tree->right = NULL;
+ tree->values.literalFromCast = 1;
+ TETYPE (tree) = getSpec (TTYPE (tree));
+ return tree;
+ }
+ }
+ if (IS_GENPTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) && !IS_GENPTR (RTYPE (tree)) && (resultType != RESULT_TYPE_GPTR))
+ {
+ DCL_TYPE (LTYPE (tree)) = DCL_TYPE (RTYPE (tree));
}
- }
TTYPE (tree) = LTYPE (tree);
LRVAL (tree) = 1;
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 */
/* 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; */
+ /* type1 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: */
/* } */
assigntree = newNode ('=',
newAst_VALUE (symbolVal (temparg)),
passedarg);
+ assigntree->initMode=1; // tell that assignment is initializer
inlinetree->right = newNode (NULLOP,
assigntree,
inlinetree->right);
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++;
}
fixupInline (inlinetree, inlinetree->level);
inlineState.count++;
}
-
}
/* Recursively continue to search for functions to inline. */
}
}
-
/*-----------------------------------------------------------------*/
/* 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);