newAst_ (unsigned type)
{
ast *ex;
- static int oldLineno = 0;
ex = Safe_alloc ( sizeof (ast));
ex->type = type;
- ex->lineno = (noLineno ? oldLineno : lexLineno);
+ ex->lineno = (noLineno ? 0 : lexLineno);
ex->filename = lexFilename;
ex->level = NestLevel;
ex->block = currBlockno;
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;
tempvar1 = replaceAstWithTemporary(&(target->left));
if (hasSEFcalls(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");
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;
}
/* 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)
{
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;
}
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;
}
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;
/* 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);
(*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;
}
}
- 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;
&& 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))
list2expr (sym->ival));
}
- setAstLineno (work, sym->lineDef);
+ setAstFileLine (work, sym->fileDef, sym->lineDef);
sym->ival = NULL;
if (staticAutos)
}
/* update lineno for error msg */
+ filename = sym->fileDef;
lineno = sym->lineDef;
- setAstLineno (ilist->init.node, sym->lineDef);
+ setAstFileLine (ilist->init.node, sym->fileDef, sym->lineDef);
if (IS_AGGREGATE (sym->type)) {
work = initAggregates (sym, sym->ival, NULL);
}
// just to be sure
- setAstLineno (work, sym->lineDef);
+ setAstFileLine (work, sym->fileDef, sym->lineDef);
sym->ival = NULL;
if (init)
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 */
{
return cexpr->opval.val;
}
- return NULL;
+ return NULL;
}
/*-----------------------------------------------------------------*/
{
*end = newNode ('+', condExpr->left->right,
- newAst_VALUE (constVal ("1")));
+ newAst_VALUE (constCharVal (1)));
break;
}
return FALSE;
}
/*-----------------------------------------------------------------*/
-/* isConformingBody - the loop body has to conform to a set of rules */
-/* for the loop to be considered reversible read on for rules */
+/* isConformingBody - the loop body has to conform to a set of */
+/* rules for the loop to be considered reversible read on for rules*/
/*-----------------------------------------------------------------*/
bool
isConformingBody (ast * pbody, symbol * sym, ast * body)
/* we are going to do a pre-order traversal of the
tree && check for the following conditions. (essentially
a set of very shallow tests )
- a) the sym passed does not participate in
- any arithmetic operation
+ a) the sym passed does not participate in any arithmetic operation
b) There are no function calls
c) all jumps are within the body
d) address of loop control variable not taken
- e) if an assignment has a pointer on the
- left hand side make sure right does not have
- loop control variable */
+ e) if an assignment has a pointer on the left hand side make sure
+ right does not have loop control variable
+ */
/* if we reach the end or a leaf then true */
if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
/* if right is NULL then unary operation */
/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*----------------------------*/
/* address of */
-/*----------------------------*/
+ /*----------------------------*/
if (!pbody->right)
{
if (IS_AST_SYM_VALUE (pbody->left) &&
if (astHasVolatile (pbody->left))
return FALSE;
- if (astHasDeref(pbody->right)) return FALSE;
+ if (astHasDeref(pbody->right))
+ return FALSE;
return isConformingBody (pbody->left, sym, body) &&
isConformingBody (pbody->right, sym, body);
assert ("Parser should not have generated this\n");
/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*----------------------------*/
/* comma operator */
-/*----------------------------*/
+ /*----------------------------*/
case ',':
return isConformingBody (pbody->left, sym, body) &&
isConformingBody (pbody->right, sym, body);
/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*----------------------------*/
/* function call */
-/*----------------------------*/
+ /*----------------------------*/
case CALL:
- /* if local & not passed as paramater then ok */
- if (sym->level && !astHasSymbol(pbody->right,sym))
+ /* if local & not passed as parameter &
+ not used to find the function then ok */
+ if (sym->level && !astHasSymbol (pbody->right, sym) &&
+ !astHasSymbol (pbody->left, sym))
+ {
return TRUE;
+ }
return FALSE;
/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*----------------------------*/
/* return statement */
-/*----------------------------*/
+ /*----------------------------*/
case RETURN:
return FALSE;
return isConformingBody (pbody->left, sym, body) &&
isConformingBody (pbody->right, sym, body);
-
-
-
}
/*-----------------------------------------------------------------*/
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));
}
end));
replLoopSym (loop->left, sym);
- setAstLineno (rloop, init->lineno);
+ setAstFileLine (rloop, init->filename, init->lineno);
rloop = newNode (NULLOP,
newNode ('=',
newNode (NULLOP,
newNode (SUB_ASSIGN,
newAst_VALUE (symbolVal (sym)),
- newAst_VALUE (constVal ("1"))),
+ newAst_VALUE (constCharVal (1))),
rloop))));
rloop->lineno=init->lineno;
}
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 */
/*----------------------------*/
/* leaf has been reached */
/*----------------------------*/
+ filename = tree->filename;
lineno = tree->lineno;
/* if this is of type value */
/* just get the type */
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
{
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;
}
/* 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, resultTypeProp, TRUE);
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);
(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;
}
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;
}
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;
if (!options.lessPedantic)
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;
/* (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);
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);
}
ex->values.sym = decl;
ex->level++;
+ ex->filename = NULL;
ex->lineno = 0;
return ex;
}
label->islbl = 1;
label->key = labelKey++;
rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
+ rValue->filename = NULL;
rValue->lineno = 0;
return rValue;
(int) ulFromVal (caseVal->opval.val));
rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
+ rexpr->filename = 0;
rexpr->lineno = 0;
return rexpr;
}
/* 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 */
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;
}
fixupInlineLabel (symbol * sym)
{
char name[SDCC_NAME_MAX + 1];
-
+
SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count);
strcpy (sym->name, name);
}
static void
copyAstLoc (ast * dest, ast * src)
{
- dest->lineno = src->lineno;
dest->filename = src->filename;
+ dest->lineno = src->lineno;
dest->level = src->level;
dest->block = src->block;
dest->seqPoint = src->seqPoint;
-
+
}
while (args)
{
symbol * temparg;
- ast * passedarg;
ast * assigntree;
- symbol * parm = copySymbol (args->sym);
+ 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);
- passedarg = inlineFindParm (tree->right, argIndex);
assigntree = newNode ('=',
newAst_VALUE (symbolVal (temparg)),
passedarg);
assigntree,
inlinetree->right);
+ parm = copySymbol (args->sym);
inlineAddDecl (parm, inlinetree2, FALSE);
parm->_isparm = 0;