+2003-12-18 Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+ * support/Util/SDCCerr.h,
+ * support/Util/SDCCerr.c (E_NOT_ALLOWED),
+ * src/SDCC.y (struct_declaration, struct_or_union_specifier): complain
+ about storage class and 'at' used inside struct or union
+ * src/SDCCBBlock.c (iCodeFromeBBlock),
+ * src/SDCCcse.c (ifxOptimize),
+ * src/SDCCglue.c (emitRegularMap, initPointer, printIvalStruct,
+ printIvalArray, printiValFuncPtr, printIvalCharPtr, printIvalPtr,
+ printIval, emitStaticSeg, emitOverlay),
+ * src/SDCClabel.c (deleteIfx),
+ * src/SDCCopt.c (replaceRegEqv, eBBlockFromiCode),
+ * src/SDCCast.c (resolveSymbols, createIvalStruct, createIvalArray,
+ gatherAutoInit, processParms),
+ * support/Util/SDCCerr.h,
+ * support/Util/SDCCerr.c (werrorfl): Support for better error location
+ reporting for post-parse errors.
+
2003-12-16 Erik Petrich <epetrich@ivorytower.norman.ok.us>
* src/SDCCval.c (valPlus, valMinus, valShift): fixed some problems with
| declaration_list compound_statement
{
werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
- fprintf(stderr, "case 1\n");
exit(1);
}
;
structdef *sdef ;
symbol *sym, *dsym;
- // check for duplicate structure members
+ // check for errors in structure members
for (sym=$4; sym; sym=sym->next) {
+ if (IS_ABSOLUTE(sym->etype)) {
+ werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "'at'");
+ SPEC_ABSA(sym->etype) = 0;
+ }
+ if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
+ werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "storage class");
+ SPEC_SCLS(sym->etype) = 0;
+ }
for (dsym=sym->next; dsym; dsym=dsym->next) {
if (strcmp(sym->name, dsym->name)==0) {
- werror(E_DUPLICATE_MEMBER,
+ werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER,
$1==STRUCT ? "struct" : "union", sym->name);
}
}
/* add this type to all the symbols */
symbol *sym ;
for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
+ sym_link *btype = copyLinkChain($1);
/* make the symbol one level up */
sym->level-- ;
- pointerTypes(sym->type,copyLinkChain($1));
+ pointerTypes(sym->type,btype);
if (!sym->type) {
- sym->type = copyLinkChain($1);
+ sym->type = btype;
sym->etype = getSpec(sym->type);
}
else
- addDecl (sym,0,copyLinkChain($1));
+ addDecl (sym,0,btype);
/* make sure the type is complete and sane */
checkTypeSanity(sym->etype, sym->name);
}
for (sym=$3; sym; sym=sym->next) {
for (dsym=sym->next; dsym; dsym=dsym->next) {
if (strcmp(sym->name, dsym->name)==0) {
- werror(E_DUPLICATE_MEMBER, "enum", sym->name);
+ werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER, "enum", sym->name);
_error++;
}
}
| declarator2 '(' parameter_identifier_list ')'
{
werror(E_OLD_STYLE,$1->name) ;
- fprintf(stderr, "case 2\n");
/* assume it returns an int */
$1->type = $1->etype = newIntLink();
$$ = $1 ;
while (ic);
if (foundNonlabel && ic)
{
- werror (W_CODE_UNREACH, ic->filename, ic->lineno);
+ werrorfl (ic->filename, ic->lineno, W_CODE_UNREACH);
continue;
}
}
tree->trueLabel->name)))
tree->trueLabel = csym;
else
- werror (E_LABEL_UNDEF, tree->trueLabel->name);
+ werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
+ tree->trueLabel->name);
}
if (tree->falseLabel)
tree->falseLabel->name)))
tree->falseLabel = csym;
else
- werror (E_LABEL_UNDEF, tree->falseLabel->name);
+ werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
+ tree->falseLabel->name);
}
}
tree->opval.val->sym->name);
if (!csym)
- werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
+ werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
+ tree->opval.val->sym->name);
else
tree->opval.val->sym = csym;
tree->opval.val->sym->etype = newIntLink ();
tree->opval.val->etype = tree->opval.val->etype;
tree->opval.val->type = tree->opval.val->sym->type;
- werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
+ werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
+ tree->opval.val->sym->name);
+ //tree->opval.val->sym->undefined = 1;
allocVariables (tree->opval.val->sym);
}
else
/* exist and this is not defined as a variable arg */
if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
{
+ //if (func->type==EX_VALUE && func->opval.val->sym->undefined)
+ // return 1; /* Already gave them an undefined function error */
werror (E_TOO_MANY_PARMS);
return 1;
}
}
if (iloop) {
- werror (W_EXCESS_INITIALIZERS, "struct",
- sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
+ werrorfl (filename, sym->opval.val->sym->lineDef,
+ W_EXCESS_INITIALIZERS, "struct",
+ sym->opval.val->sym->name);
}
return rast;
char *name=sym->opval.val->sym->name;
int lineno=sym->opval.val->sym->lineDef;
- werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
+ werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
}
}
else
// there has to be a better way
char *name=sym->opval.val->sym->name;
int lineno=sym->opval.val->sym->lineDef;
- werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
+ werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
break;
}
work = initAggregates (sym, sym->ival, NULL);
} else {
if (getNelements(sym->type, sym->ival)>1) {
- werror (W_EXCESS_INITIALIZERS, "scalar",
- sym->name, sym->lineDef);
+ werrorfl (filename, sym->lineDef,
+ W_EXCESS_INITIALIZERS, "scalar",
+ sym->name);
}
work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
list2expr (sym->ival));
work = initAggregates (sym, sym->ival, NULL);
} else {
if (getNelements(sym->type, sym->ival)>1) {
- werror (W_EXCESS_INITIALIZERS, "scalar",
- sym->name, sym->lineDef);
+ werrorfl (filename, sym->lineDef,
+ W_EXCESS_INITIALIZERS, "scalar",
+ sym->name);
}
work = newNode ('=', newAst_VALUE (symbolVal (sym)),
list2expr (sym->ival));
{
ast *dtl, *dtr;
+ #if 0
+ if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
+ {
+ if (tree->left && tree->left->type == EX_OPERAND
+ && (tree->left->opval.op == INC_OP
+ || tree->left->opval.op == DEC_OP)
+ && tree->left->left)
+ {
+ tree->left->right = tree->left->left;
+ tree->left->left = NULL;
+ }
+ if (tree->right && tree->right->type == EX_OPERAND
+ && (tree->right->opval.op == INC_OP
+ || tree->right->opval.op == DEC_OP)
+ && tree->right->left)
+ {
+ tree->right->right = tree->right->left;
+ tree->right->left = NULL;
+ }
+ }
+ #endif
+
dtl = decorateType (tree->left);
/* delay right side for '?' operator since conditional macro expansions might
rely on this */
/* the price */
computeControlFlow (ebbs, count, 1);
if (!options.lessPedantic) {
- werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+ werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
}
return;
}
{
if (!options.lessPedantic) {
- werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+ werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
}
if (IS_OP_VOLATILE (IC_COND (ic)))
{
ival = initAggregates (sym, sym->ival, NULL);
} else {
if (getNelements(sym->type, sym->ival)>1) {
- werror (W_EXCESS_INITIALIZERS, "scalar",
- sym->name, sym->lineDef);
+ werrorfl (filename, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
+ sym->name);
}
ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
decorateType (resolveSymbols (list2expr (sym->ival))));
else {
int size = getSize (sym->type);
if (size==0) {
- werror(E_UNKNOWN_SIZE,sym->name);
+ werrorfl (filename, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
}
/* allocate space */
if (options.debug) {
return val;
}
wrong:
- werror (E_INCOMPAT_PTYPES);
+ if (expr)
+ werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
+ else
+ werror (E_INCOMPAT_PTYPES);
return NULL;
}
sflds = SPEC_STRUCT (type)->fields;
if (ilist->type != INIT_DEEP) {
- werror (E_INIT_STRUCT, sym->name);
+ werrorfl (filename, sym->lineDef, E_INIT_STRUCT, sym->name);
return;
}
}
}
if (iloop) {
- werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
+ werrorfl (filename, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
}
return;
}
/* by a string */
if (IS_CHAR (type->next)) {
if (!IS_LITERAL(list2val(ilist)->etype)) {
- werror (E_CONST_EXPECTED);
+ werrorfl (filename, ilist->lineno, E_CONST_EXPECTED);
return;
}
if (printIvalChar (type,
/* not the special case */
if (ilist->type != INIT_DEEP)
{
- werror (E_INIT_STRUCT, sym->name);
+ werrorfl (filename, ilist->lineno, E_INIT_STRUCT, sym->name);
return;
}
printIval (sym, type->next, iloop, oFile);
if (++size > DCL_ELEM(type)) {
- werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
+ werrorfl (filename, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
break;
}
}
if (IS_LITERAL(val->etype)) {
if (compareType(type,val->etype)==0) {
- werror (E_INCOMPAT_TYPES);
+ werrorfl (filename, ilist->lineno, E_INCOMPAT_TYPES);
printFromToType (val->type, type);
}
printIvalCharPtr (NULL, type, val, oFile);
case 3:
if (IS_GENPTR(type) && floatFromVal(val)!=0) {
// non-zero mcs51 generic pointer
- werror (E_LITERAL_GENERIC);
+ werrorfl (filename, sym->lineDef, E_LITERAL_GENERIC);
}
if (port->little_endian) {
fprintf (oFile, "\t.byte %s,%s,%s\n",
case 4:
if (IS_GENPTR(type) && floatFromVal(val)!=0) {
// non-zero ds390 generic pointer
- werror (E_LITERAL_GENERIC);
+ werrorfl (filename, sym->lineDef, E_LITERAL_GENERIC);
}
if (port->little_endian) {
fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
/* check the type */
if (compareType (type, val->type) == 0) {
- werror (W_INIT_WRONG);
+ werrorfl (filename, ilist->lineno, W_INIT_WRONG);
printFromToType (val->type, type);
}
if (!ilist)
return;
- /* update line number for error msgs */
- lineno=sym->lineDef;
-
/* if structure then */
if (IS_STRUCT (type))
{
if (ilist->type!=INIT_NODE) {
// or a 1-element list
if (ilist->init.deep->next) {
- werror (W_EXCESS_INITIALIZERS, "scalar",
- sym->name, sym->lineDef);
+ werrorfl (filename, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
+ sym->name);
} else {
ilist=ilist->init.deep;
}
IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
// no sweat
} else {
- werror (E_TYPE_MISMATCH, "assignment", " ");
+ werrorfl (filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
printFromToType(itype, type);
}
}
int size = getSize (sym->type);
if (size==0) {
- werror(E_UNKNOWN_SIZE,sym->name);
+ werrorfl (filename, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
}
fprintf (out, "%s:\n", sym->rname);
/* special case for character strings */
int size = getSize(sym->type);
if (size==0) {
- werror(E_UNKNOWN_SIZE,sym->name);
+ werrorfl (filename, sym->lineDef, E_UNKNOWN_SIZE);
}
if (options.debug)
fprintf (afile, "==.\n");
{
if (!options.lessPedantic)
{
- werror (W_CONTROL_FLOW, loop->filename, loop->lineno);
+ werrorfl (loop->filename, loop->lineno, W_CONTROL_FLOW);
}
hTabDeleteItem (&labelRef, key, loop, DELETE_ITEM, NULL);
IS_TRUE_SYMOP (IC_COND (ic)) &&
isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
{
- werror (W_LOCAL_NOINIT,
- OP_SYMBOL (IC_COND (ic))->name,
- ic->filename, ic->lineno);
+ werrorfl (ic->filename, ic->lineno,
+ W_LOCAL_NOINIT,
+ OP_SYMBOL (IC_COND (ic))->name);
OP_REQV (IC_COND (ic)) = NULL;
OP_SYMBOL (IC_COND (ic))->allocreq = 1;
}
IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
{
- werror (W_LOCAL_NOINIT,
- OP_SYMBOL (IC_JTCOND (ic))->name,
- ic->filename, ic->lineno);
+ werrorfl (ic->filename, ic->lineno,
+ W_LOCAL_NOINIT,
+ OP_SYMBOL (IC_JTCOND (ic))->name);
OP_REQV (IC_JTCOND (ic)) = NULL;
OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
}
IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
{
- werror (W_LOCAL_NOINIT,
- OP_SYMBOL (IC_RIGHT (ic))->name,
- ic->filename, ic->lineno);
+ werrorfl (ic->filename, ic->lineno,
+ W_LOCAL_NOINIT,
+ OP_SYMBOL (IC_RIGHT (ic))->name);
OP_REQV (IC_RIGHT (ic)) = NULL;
OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
}
IS_TRUE_SYMOP (IC_LEFT (ic)) &&
isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
{
- werror (W_LOCAL_NOINIT,
- OP_SYMBOL (IC_LEFT (ic))->name,
- ic->filename, ic->lineno);
+ werrorfl (ic->filename, ic->lineno,
+ W_LOCAL_NOINIT,
+ OP_SYMBOL (IC_LEFT (ic))->name);
OP_REQV (IC_LEFT (ic)) = NULL;
OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
}
bp;
bp=setNextItem(ebbs[saveCount-1]->predList)) {
if (bp->ech->op != RETURN) {
- werror (W_VOID_FUNC, currFunc->name);
+ werrorfl (bp->ech->filename, bp->ech->lineno,
+ W_VOID_FUNC, currFunc->name);
}
}
}
{ E_TERMINATING, ERROR_LEVEL_ERROR,
"Compiler Terminating , contact author with source" },
{ W_LOCAL_NOINIT, ERROR_LEVEL_WARNING,
- "'auto' variable '%s' may be used before initialization at %s(%d)" },
+ "'auto' variable '%s' may be used before initialization" },
{ W_NO_REFERENCE, ERROR_LEVEL_WARNING,
"in function %s unreferenced %s : '%s'" },
{ E_OP_UNKNOWN_SIZE, ERROR_LEVEL_ERROR,
{ W_FUNC_TOO_LARGE, ERROR_LEVEL_WARNING,
"function '%s' too large for global optimization" },
{ W_CONTROL_FLOW, ERROR_LEVEL_PEDANTIC,
- "conditional flow changed by optimizer '%s(%d)':so said EVELYN the modified DOG" },
+ "conditional flow changed by optimizer: so said EVELYN the modified DOG" },
{ W_PTR_TYPE_INVALID, ERROR_LEVEL_WARNING,
"invalid type specifier for pointer type; specifier ignored" },
{ W_IMPLICIT_FUNC, ERROR_LEVEL_WARNING,
{ W_CONST_RANGE, ERROR_LEVEL_WARNING,
"constant is out of range %s" },
{ W_CODE_UNREACH, ERROR_LEVEL_PEDANTIC,
- "unreachable code %s(%d)" },
+ "unreachable code" },
{ E_NONPTR2_GENPTR, ERROR_LEVEL_ERROR,
"non-pointer type cast to generic pointer" },
{ W_POSSBUG, ERROR_LEVEL_WARNING,
{ E_TWO_OR_MORE_STORAGE_CLASSES, ERROR_LEVEL_ERROR,
"two or more storage classes in declaration for '%s'" },
{ W_EXCESS_INITIALIZERS, ERROR_LEVEL_WARNING,
- "excess elements in %s initializer after `%s' at line %d" },
+ "excess elements in %s initializer after `%s'" },
{ E_ARGUMENT_MISSING, ERROR_LEVEL_ERROR,
"Option %s requires an argument." },
{ W_STRAY_BACKSLASH, ERROR_LEVEL_WARNING,
"unmatched #pragma SAVE and #pragma RESTORE" },
{ E_INVALID_CRITICAL, ERROR_LEVEL_ERROR,
"not allowed in a critical section" },
+{ E_NOT_ALLOWED, ERROR_LEVEL_ERROR,
+ "%s not allowed here" },
};
/*
va_end(marker);
}
+/*
+-------------------------------------------------------------------------------
+werrorfl - Output a standard eror message with variable number of arguements.
+ Use a specified filename and line number instead of the default.
+
+-------------------------------------------------------------------------------
+*/
+
+void werrorfl (char *newFilename, int newLineno, int errNum, ...)
+{
+ char *oldFilename = filename;
+ int oldLineno = lineno;
+
+ filename = newFilename;
+ lineno = newLineno;
+
+ va_list marker;
+ va_start(marker,errNum);
+ vwerror(errNum, marker);
+ va_end(marker);
+
+ filename = oldFilename;
+ lineno = oldLineno;
+}
+
/*
-------------------------------------------------------------------------------
#define E_FUNC_ATTR 169 /* function attribute without function */
#define W_SAVE_RESTORE 170 /* unmatched #pragma SAVE and #pragma RESTORE */
#define E_INVALID_CRITICAL 171 /* operation invalid in critical sequence */
+#define E_NOT_ALLOWED 172 /* %s not allowed here */
/** Describes the maximum error level that will be logged. Any level
* includes all of the levels listed after it.
void werror (int errNum, ... ) ;
+/*
+-------------------------------------------------------------------------------
+werrorfl - Output a standard eror message with variable number of arguements.
+ Use a specified filename and line number instead of the default.
+
+-------------------------------------------------------------------------------
+*/
+
+void werrorfl (char *newFilename, int newLineno, int errNum, ...) ;
+
/*
-------------------------------------------------------------------------------
fatal - Output a standard eror message with variable number of arguements and