1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-11 11:30:13 +00:00

Rewrote handling of the -W command line option. It is now used to enable or

disable warnings by name.


git-svn-id: svn://svn.cc65.org/cc65/trunk@4348 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2009-10-08 13:29:35 +00:00
parent 58e8826da2
commit b55419af59
8 changed files with 299 additions and 152 deletions

View File

@ -64,7 +64,7 @@ Short options:
-Os Inline some known functions
-T Include source as comment
-V Print the compiler version number
-W Suppress warnings
-W name[,name] Enable or disable warnings
-d Debug mode
-g Add debug info to object file
-h Help (this text)
@ -383,11 +383,27 @@ Here is a description of all the command line options:
<label id="option-W">
<tag><tt>-W</tt></tag>
<tag><tt>-W name[,name]</tt></tag>
This option will suppress any warnings generated by the compiler. Since
any source file may be written in a manner that it will not produce
compiler warnings, using this option is usually not a good idea.
This option allows to control warnings generated by the compiler. It is
followed by a comma separated list of warnings that should be enabled or
disabled. To disable a warning, its name is prefixed by a minus sign. If
no such prefix exists, or the name is prefixed by a plus sign, the warning
is enabled.
The following warning names are currently recognized:
<descrip>
<tag><tt/error/</tag>
Treat all warnings as errors.
<tag><tt/unknown-pragma/</tag>
Warn about known #pragmas.
<tag><tt/unused-label/</tag>
Warn about unused labels.
<tag><tt/unused-param/</tag>
Warn about unused function parameters.
<tag><tt/unused-var/</tag>
Warn about unused variables.
</descrip>
</descrip><p>

View File

@ -60,115 +60,37 @@
unsigned ErrorCount = 0;
unsigned WarningCount = 0;
/* Warning and error options */
IntStack WarnEnable = INTSTACK(1); /* Enable warnings */
IntStack WarningsAreErrors = INTSTACK(0); /* Treat warnings as errors */
IntStack WarnUnusedLabel = INTSTACK(1); /* Warn about unused labels */
IntStack WarnUnusedParam = INTSTACK(1); /* Warn about unused parameters */
IntStack WarnUnusedVar = INTSTACK(1); /* Warn about unused variables */
IntStack WarnUnknownPragma = INTSTACK(1); /* Warn about unknown #pragmas */
/* Map the name of a warning to the intstack that holds its state */
typedef struct WarnMapEntry WarnMapEntry;
struct WarnMapEntry {
IntStack* Stack;
const char* Name;
};
static WarnMapEntry WarnMap[] = {
/* Keep sorted, even if this isn't used for now */
{ &WarningsAreErrors, "error" },
{ &WarnUnknownPragma, "unknown-pragma" },
{ &WarnUnusedLabel, "unused-label" },
{ &WarnUnusedParam, "unused-param" },
{ &WarnUnusedVar, "unused-var" },
};
/*****************************************************************************/
/* Code */
/* Handling of fatal errors */
/*****************************************************************************/
static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
/* Print warning message - internal function. */
{
if (!IS_Get (&WarnDisable)) {
fprintf (stderr, "%s(%u): Warning: ", Filename, LineNo);
vfprintf (stderr, Msg, ap);
fprintf (stderr, "\n");
if (Line) {
Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
}
++WarningCount;
}
}
void Warning (const char* Format, ...)
/* Print warning message. */
{
va_list ap;
va_start (ap, Format);
IntWarning (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap);
va_end (ap);
}
void LIWarning (const LineInfo* LI, const char* Format, ...)
/* Print a warning message with the line info given explicitly */
{
va_list ap;
va_start (ap, Format);
IntWarning (GetInputName (LI), GetInputLine (LI), Format, ap);
va_end (ap);
}
void PPWarning (const char* Format, ...)
/* Print warning message. For use within the preprocessor. */
{
va_list ap;
va_start (ap, Format);
IntWarning (GetCurrentFile(), GetCurrentLine(), Format, ap);
va_end (ap);
}
static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
/* Print an error message - internal function*/
{
fprintf (stderr, "%s(%u): Error: ", Filename, LineNo);
vfprintf (stderr, Msg, ap);
fprintf (stderr, "\n");
if (Line) {
Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
}
++ErrorCount;
if (ErrorCount > 10) {
Fatal ("Too many errors");
}
}
void Error (const char* Format, ...)
/* Print an error message */
{
va_list ap;
va_start (ap, Format);
IntError (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap);
va_end (ap);
}
void LIError (const LineInfo* LI, const char* Format, ...)
/* Print an error message with the line info given explicitly */
{
va_list ap;
va_start (ap, Format);
IntError (GetInputName (LI), GetInputLine (LI), Format, ap);
va_end (ap);
}
void PPError (const char* Format, ...)
/* Print an error message. For use within the preprocessor. */
{
va_list ap;
va_start (ap, Format);
IntError (GetCurrentFile(), GetCurrentLine(), Format, ap);
va_end (ap);
}
void Fatal (const char* Format, ...)
/* Print a message about a fatal error and die */
{
@ -232,6 +154,150 @@ void Internal (const char* Format, ...)
/*****************************************************************************/
/* Handling of errors */
/*****************************************************************************/
static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
/* Print an error message - internal function*/
{
fprintf (stderr, "%s(%u): Error: ", Filename, LineNo);
vfprintf (stderr, Msg, ap);
fprintf (stderr, "\n");
if (Line) {
Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
}
++ErrorCount;
if (ErrorCount > 10) {
Fatal ("Too many errors");
}
}
void Error (const char* Format, ...)
/* Print an error message */
{
va_list ap;
va_start (ap, Format);
IntError (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap);
va_end (ap);
}
void LIError (const LineInfo* LI, const char* Format, ...)
/* Print an error message with the line info given explicitly */
{
va_list ap;
va_start (ap, Format);
IntError (GetInputName (LI), GetInputLine (LI), Format, ap);
va_end (ap);
}
void PPError (const char* Format, ...)
/* Print an error message. For use within the preprocessor. */
{
va_list ap;
va_start (ap, Format);
IntError (GetCurrentFile(), GetCurrentLine(), Format, ap);
va_end (ap);
}
/*****************************************************************************/
/* Handling of warnings */
/*****************************************************************************/
static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
/* Print warning message - internal function. */
{
if (IS_Get (&WarningsAreErrors)) {
/* Treat the warning as an error */
IntError (Filename, LineNo, Msg, ap);
} else if (IS_Get (&WarnEnable)) {
fprintf (stderr, "%s(%u): Warning: ", Filename, LineNo);
vfprintf (stderr, Msg, ap);
fprintf (stderr, "\n");
if (Line) {
Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
}
++WarningCount;
}
}
void Warning (const char* Format, ...)
/* Print warning message. */
{
va_list ap;
va_start (ap, Format);
IntWarning (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap);
va_end (ap);
}
void LIWarning (const LineInfo* LI, const char* Format, ...)
/* Print a warning message with the line info given explicitly */
{
va_list ap;
va_start (ap, Format);
IntWarning (GetInputName (LI), GetInputLine (LI), Format, ap);
va_end (ap);
}
void PPWarning (const char* Format, ...)
/* Print warning message. For use within the preprocessor. */
{
va_list ap;
va_start (ap, Format);
IntWarning (GetCurrentFile(), GetCurrentLine(), Format, ap);
va_end (ap);
}
IntStack* FindWarning (const char* Name)
/* Search for a warning in the WarnMap table and return a pointer to the
* intstack that holds its state. Return NULL if there is no such warning.
*/
{
unsigned I;
/* For now, do a linear search */
for (I = 0; I < sizeof(WarnMap) / sizeof (WarnMap[0]); ++I) {
if (strcmp (WarnMap[I].Name, Name) == 0) {
return WarnMap[I].Stack;
}
}
return 0;
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void ErrorReport (void)
/* Report errors (called at end of compile) */
{

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998-2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2009, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -40,6 +40,7 @@
/* common */
#include "attrib.h"
#include "intstack.h"
/* cc65 */
#include "lineinfo.h"
@ -56,6 +57,14 @@
extern unsigned ErrorCount;
extern unsigned WarningCount;
/* Warning and error options */
extern IntStack WarnEnable; /* Enable warnings */
extern IntStack WarningsAreErrors; /* Treat warnings as errors */
extern IntStack WarnUnusedLabel; /* Warn about unused labels */
extern IntStack WarnUnusedParam; /* Warn about unused parameters */
extern IntStack WarnUnusedVar; /* Warn about unused variables */
extern IntStack WarnUnknownPragma; /* Warn about unknown #pragmas */
/*****************************************************************************/
@ -64,14 +73,11 @@ extern unsigned WarningCount;
void Warning (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print warning message. */
void Fatal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
/* Print a message about a fatal error and die */
void LIWarning (const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 2, 3)));
/* Print a warning message with the line info given explicitly */
void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print warning message. For use within the preprocessor. */
void Internal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
/* Print a message about an internal compiler error and die. */
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print an error message */
@ -82,11 +88,19 @@ void LIError (const LineInfo* LI, const char* Format, ...) attribute ((format (p
void PPError (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print an error message. For use within the preprocessor. */
void Fatal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
/* Print a message about a fatal error and die */
void Warning (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print warning message. */
void Internal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
/* Print a message about an internal compiler error and die. */
void LIWarning (const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 2, 3)));
/* Print a warning message with the line info given explicitly */
void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print warning message. For use within the preprocessor. */
IntStack* FindWarning (const char* Name);
/* Search for a warning in the WarnMap table and return a pointer to the
* intstack that holds its state. Return NULL if there is no such warning.
*/
void ErrorReport (void);
/* Report errors (called at end of compile) */

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 1998-2009, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -50,7 +50,6 @@ unsigned char PreprocessOnly = 0; /* Just preprocess the input */
unsigned RegisterSpace = 6; /* Space available for register vars */
/* Stackable options */
IntStack WarnDisable = INTSTACK(0); /* Suppress warnings */
IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */
IntStack InlineStdFuncs = INTSTACK(0); /* Inline some known functions */
IntStack EnableRegVars = INTSTACK(0); /* Enable register variables */

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 1998-2009, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -57,7 +57,6 @@ extern unsigned char PreprocessOnly; /* Just preprocess the input */
extern unsigned RegisterSpace; /* Space available for register vars */
/* Stackable options */
extern IntStack WarnDisable; /* Suppress warnings */
extern IntStack WritableStrings; /* Literal strings are r/w */
extern IntStack InlineStdFuncs; /* Inline some known functions */
extern IntStack EnableRegVars; /* Enable register variables */

View File

@ -48,6 +48,7 @@
#include "mmodel.h"
#include "print.h"
#include "segnames.h"
#include "strbuf.h"
#include "target.h"
#include "tgttrans.h"
#include "version.h"
@ -373,7 +374,7 @@ static void OptCodeSize (const char* Opt, const char* Arg)
/* Numeric argument expected */
if (sscanf (Arg, "%u%c", &Factor, &BoundsCheck) != 1 ||
Factor < 10 || Factor > 1000) {
InvArg (Opt, Arg);
AbEnd ("Argument for %s is invalid", Opt);
}
IS_Set (&CodeSizeFactor, Factor);
}
@ -396,7 +397,7 @@ static void OptCPU (const char* Opt, const char* Arg)
CPU = FindCPU (Arg);
if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 &&
CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280) {
InvArg (Opt, Arg);
AbEnd ("Invalid argument for %s: `%s'", Opt, Arg);
}
}
@ -584,7 +585,7 @@ static void OptRegisterSpace (const char* Opt, const char* Arg)
{
/* Numeric argument expected */
if (sscanf (Arg, "%u", &RegisterSpace) != 1 || RegisterSpace > 256) {
InvArg (Opt, Arg);
AbEnd ("Argument for option %s is invalid", Opt);
}
}
@ -626,7 +627,7 @@ static void OptStandard (const char* Opt, const char* Arg)
/* Find the standard from the given name */
standard_t Std = FindStandard (Arg);
if (Std == STD_UNKNOWN) {
InvArg (Opt, Arg);
AbEnd ("Invalid argument for %s: `%s'", Opt, Arg);
} else if (IS_Get (&Standard) != STD_UNKNOWN) {
AbEnd ("Option %s given more than once", Opt);
} else {
@ -674,6 +675,52 @@ static void OptVersion (const char* Opt attribute ((unused)),
static void OptWarning (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the -W option */
{
StrBuf W = AUTO_STRBUF_INITIALIZER;
/* Arg is a list of suboptions, separated by commas */
while (Arg) {
const char* Pos;
int Enabled = 1;
IntStack* S;
/* The suboption may be prefixed with '-' or '+' */
if (*Arg == '-') {
Enabled = 0;
++Arg;
} else if (*Arg == '+') {
/* This is the default */
++Arg;
}
/* Get the next suboption */
Pos = strchr (Arg, ',');
if (Pos) {
SB_CopyBuf (&W, Arg, Pos - Arg);
Arg = Pos + 1;
} else {
SB_CopyStr (&W, Arg);
Arg = 0;
}
SB_Terminate (&W);
/* Search for the warning */
S = FindWarning (SB_GetConstBuf (&W));
if (S == 0) {
InvArg (Opt, SB_GetConstBuf (&W));
}
IS_Set (S, Enabled);
}
/* Free allocated memory */
SB_Done (&W);
}
static void OptWritableStrings (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Make string literals writable */
@ -839,7 +886,7 @@ int main (int argc, char* argv[])
break;
case 'W':
IS_Set (&WarnDisable, 1);
OptWarning (Arg, GetArg (&I, 2));
break;
default:

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* (C) 1998-2009, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -501,7 +501,7 @@ static void ParsePragma (void)
break;
case PR_WARN:
FlagPragma (&B, &WarnDisable);
FlagPragma (&B, &WarnEnable);
break;
case PR_ZPSYM:

View File

@ -164,12 +164,16 @@ static void CheckSymTable (SymTable* Tab)
if (((Flags & SC_AUTO) || (Flags & SC_STATIC)) && (Flags & SC_EXTERN) == 0) {
if (SymIsDef (Entry) && !SymIsRef (Entry)) {
if (Flags & SC_PARAM) {
if (IS_Get (&WarnUnusedParam)) {
Warning ("Parameter `%s' is never used", Entry->Name);
}
} else {
if (IS_Get (&WarnUnusedVar)) {
Warning ("`%s' is defined but never used", Entry->Name);
}
}
}
}
/* If the entry is a label, check if it was defined in the function */
if (Flags & SC_LABEL) {
@ -178,9 +182,11 @@ static void CheckSymTable (SymTable* Tab)
Error ("Undefined label: `%s'", Entry->Name);
} else if (!SymIsRef (Entry)) {
/* Defined but not used */
if (IS_Get (&WarnUnusedLabel)) {
Warning ("`%s' is defined but never used", Entry->Name);
}
}
}
}