Compiler: Improve the reported line number accuracy on warning 203/4 (symbol never used).

Imported from Pawn 3.1.3541+.
https://code.google.com/p/pawnscript/source/detail?r=25
This commit is contained in:
Arkshine 2014-08-15 18:40:07 +02:00
parent 65c29cafa0
commit 16e5f54507
6 changed files with 127 additions and 47 deletions

View File

@ -148,6 +148,7 @@ typedef struct s_symbol {
} dim; /* for 'dimension', both functions and arrays */
constvalue *states; /* list of state function addresses */
int fnumber; /* static global variables: file number in which the declaration is visible */
int lnumber; /* line number (in the current source file) for the declaration */
struct s_symbol **refer; /* referrer list, functions that "use" this symbol */
int numrefers; /* number of entries in the referrer list */
char *documentation; /* optional documentation string */
@ -407,6 +408,8 @@ typedef struct s_stringpair {
#define sFORCESET 1 /* force error flag on */
#define sEXPRMARK 2 /* mark start of expression */
#define sEXPRRELEASE 3 /* mark end of expression */
#define sSETLINE 4 /* set line number for the error */
#define sSETFILE 5 /* set file number for the error */
typedef enum s_regid {
sPRI, /* indicates the primary register */
@ -651,7 +654,7 @@ SC_FUNC void outval(cell val,int newline);
/* function prototypes in SC5.C */
SC_FUNC int error(int number,...) INVISIBLE;
SC_FUNC void errorset(int code);
SC_FUNC void errorset(int code, int line);
/* function prototypes in SC6.C */
SC_FUNC int assemble(FILE *fout,FILE *fin);
@ -684,6 +687,9 @@ SC_FUNC void delete_substtable(void);
SC_FUNC stringlist *insert_sourcefile(char *string);
SC_FUNC char *get_sourcefile(int index);
SC_FUNC void delete_sourcefiletable(void);
SC_FUNC stringlist *insert_inputfile(char *string);
SC_FUNC char *get_inputfile(int index);
SC_FUNC void delete_inputfiletable(void);
SC_FUNC stringlist *insert_docstring(char *string);
SC_FUNC char *get_docstring(int index);
SC_FUNC void delete_docstring(int index);
@ -780,8 +786,8 @@ SC_VDECL cell sc_stksize; /* stack size */
SC_VDECL cell sc_amxlimit; /* abstract machine size limit */
SC_VDECL int freading; /* is there an input file ready for reading? */
SC_VDECL int fline; /* the line number in the current file */
SC_VDECL short fnumber; /* number of files in the file table (debugging) */
SC_VDECL short fcurrent; /* current file being processed (debugging) */
SC_VDECL short fnumber; /* number of files in the input file table */
SC_VDECL short fcurrent; /* current file being processed */
SC_VDECL short sc_intest; /* true if inside a test */
SC_VDECL int sideeffect; /* true if an expression causes a side-effect */
SC_VDECL int stmtindent; /* current indent of the statement */

View File

@ -461,8 +461,8 @@ int pc_compile(int argc, char *argv[])
/* set global variables to their initial value */
binf=NULL;
initglobals();
errorset(sRESET);
errorset(sEXPRRELEASE);
errorset(sRESET,0);
errorset(sEXPRRELEASE,0);
lexinit();
/* make sure that we clean up on a fatal error; do this before the first
@ -597,7 +597,7 @@ int pc_compile(int argc, char *argv[])
sc_packstr=lcl_packstr;
sc_needsemicolon=lcl_needsemicolon;
sc_tabsize=lcl_tabsize;
errorset(sRESET);
errorset(sRESET,0);
/* reset the source file */
inpf=inpf_org;
freading=TRUE;
@ -662,7 +662,7 @@ int pc_compile(int argc, char *argv[])
sc_packstr=lcl_packstr;
sc_needsemicolon=lcl_needsemicolon;
sc_tabsize=lcl_tabsize;
errorset(sRESET);
errorset(sRESET,0);
/* reset the source file */
inpf=inpf_org;
freading=TRUE;
@ -671,7 +671,8 @@ int pc_compile(int argc, char *argv[])
lexinit(); /* clear internal flags of lex() */
sc_status=statWRITE; /* allow to write --this variable was reset by resetglobals() */
writeleader(&glbtab);
insert_dbgfile(inpfname);
insert_dbgfile(inpfname); /* attach to debug information */
insert_inputfile(inpfname); /* save for the error system */
if (strlen(incfname)>0) {
if (strcmp(incfname,sDEF_PREFIX)==0)
plungefile(incfname,FALSE,TRUE); /* parse "default.inc" (again) */
@ -752,6 +753,7 @@ cleanup:
delete_aliastable();
delete_pathtable();
delete_sourcefiletable();
delete_inputfiletable();
delete_dbgstringtable();
#if !defined NO_DEFINE
delete_substtable();
@ -790,7 +792,7 @@ cleanup:
#endif
int pc_addconstant(char *name,cell value,int tag)
{
errorset(sFORCESET); /* make sure error engine is silenced */
errorset(sFORCESET,0); /* make sure error engine is silenced */
sc_status=statIDLE;
add_constant(name,value,sGLOBAL,tag);
return 1;
@ -3635,7 +3637,7 @@ static int declargs(symbol *sym)
} /* for */
sym->usage|=uPROTOTYPED;
errorset(sRESET); /* reset error flag (clear the "panic mode")*/
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
return argcnt;
}
@ -4344,17 +4346,23 @@ static int testsymbols(symbol *root,int level,int testlabs,int testconst)
switch (sym->ident) {
case iLABEL:
if (testlabs) {
if ((sym->usage & uDEFINE)==0)
if ((sym->usage & uDEFINE)==0) {
error(19,sym->name); /* not a label: ... */
else if ((sym->usage & uREAD)==0)
} else if ((sym->usage & uREAD)==0) {
errorset(sSETFILE,sym->fnumber);
errorset(sSETLINE,sym->lnumber);
error(203,sym->name); /* symbol isn't used: ... */
} /* if */
} /* if */
break;
case iFUNCTN:
if ((sym->usage & (uDEFINE | uREAD | uNATIVE | uSTOCK))==uDEFINE) {
funcdisplayname(symname,sym->name);
if (strlen(symname)>0)
if (strlen(symname)>0) {
errorset(sSETFILE,sym->fnumber);
errorset(sSETLINE,sym->lnumber);
error(203,symname); /* symbol isn't used ... (and not native/stock) */
} /* if */
} /* if */
if ((sym->usage & uPUBLIC)!=0 || strcmp(sym->name,uMAINFUNC)==0)
entry=TRUE; /* there is an entry point */
@ -4363,21 +4371,31 @@ static int testsymbols(symbol *root,int level,int testlabs,int testconst)
insert_dbgsymbol(sym);
break;
case iCONSTEXPR:
if (testconst && (sym->usage & uREAD)==0)
if (testconst && (sym->usage & uREAD)==0) {
errorset(sSETFILE,sym->fnumber);
errorset(sSETLINE,sym->lnumber);
error(203,sym->name); /* symbol isn't used: ... */
} /* if */
break;
default:
/* a variable */
if (sym->parent!=NULL)
break; /* hierarchical data type */
if ((sym->usage & (uWRITTEN | uREAD | uSTOCK))==0)
error(203,sym->name); /* symbol isn't used (and not stock) */
else if ((sym->usage & (uREAD | uSTOCK | uPUBLIC))==0)
if ((sym->usage & (uWRITTEN | uREAD | uSTOCK))==0) {
errorset(sSETFILE,sym->fnumber);
errorset(sSETLINE,sym->lnumber);
error(203,sym->name,sym->lnumber); /* symbol isn't used (and not stock) */
} else if ((sym->usage & (uREAD | uSTOCK | uPUBLIC))==0) {
errorset(sSETFILE,sym->fnumber);
errorset(sSETLINE,sym->lnumber);
error(204,sym->name); /* value assigned to symbol is never used */
#if 0 // ??? not sure whether it is a good idea to force people use "const"
else if ((sym->usage & (uWRITTEN | uPUBLIC | uCONST))==0 && sym->ident==iREFARRAY)
} else if ((sym->usage & (uWRITTEN | uPUBLIC | uCONST))==0 && sym->ident==iREFARRAY) {
errorset(sSETFILE,sym->fnumber);
errorset(sSETLINE,sym->lnumber);
error(214,sym->name); /* make array argument "const" */
#endif
} /* if */
/* also mark the variable (local or global) to the debug information */
if ((sym->usage & (uWRITTEN | uREAD))!=0 && (sym->usage & uNATIVE)==0)
insert_dbgsymbol(sym);
@ -4385,6 +4403,8 @@ static int testsymbols(symbol *root,int level,int testlabs,int testconst)
sym=sym->next;
} /* while */
errorset(sEXPRRELEASE, 0); /* clear error data */
errorset(sRESET, 0);
return entry;
}
@ -4595,7 +4615,7 @@ static void statement(int *lastindent,int allow_decl)
error(36); /* empty statement */
return;
} /* if */
errorset(sRESET);
errorset(sRESET,0);
tok=lex(&val,&st);
if (tok!='{') {
@ -4722,6 +4742,7 @@ static void compound(int stmt_sameline)
int indent=-1;
cell save_decl=declared;
int count_stmt=0;
int block_start=fline; /* save line where the compound block started */
/* if there is more text on this line, we should adjust the statement indent */
if (stmt_sameline) {
@ -4749,7 +4770,7 @@ static void compound(int stmt_sameline)
nestlevel+=1; /* increase compound statement level */
while (matchtoken('}')==0){ /* repeat until compound statement is closed */
if (!freading){
needtoken('}'); /* gives error: "expected token }" */
error(30,block_start); /* compound block not closed at end of file */
break;
} else {
if (count_stmt>0 && (lastst==tRETURN || lastst==tBREAK || lastst==tCONTINUE))
@ -4787,7 +4808,7 @@ static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr,
assert(stgidx==0);
} /* if */
index=stgidx;
errorset(sEXPRMARK);
errorset(sEXPRMARK,0);
do {
/* on second round through, mark the end of the previous expression */
if (index!=stgidx)
@ -4802,7 +4823,7 @@ static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr,
} while (comma && matchtoken(',')); /* more? */
if (mark_endexpr)
markexpr(sEXPR,NULL,0); /* optionally, mark the end of the expression */
errorset(sEXPRRELEASE);
errorset(sEXPRRELEASE,0);
if (localstaging) {
stgout(index);
stgset(FALSE); /* stop staging */
@ -4819,7 +4840,7 @@ SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr)
stgset(TRUE); /* start stage-buffering */
stgget(&index,&cidx); /* mark position in code generator */
errorset(sEXPRMARK);
errorset(sEXPRMARK,0);
ident=expression(val,tag,symptr,FALSE);
stgdel(index,cidx); /* scratch generated code */
stgset(FALSE); /* stop stage-buffering */
@ -4832,7 +4853,7 @@ SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr)
if (symptr!=NULL)
*symptr=NULL;
} /* if */
errorset(sEXPRRELEASE);
errorset(sEXPRRELEASE,0);
return (ident==iCONSTEXPR);
}

View File

@ -156,15 +156,17 @@ static char *extensions[] = { ".inc", ".p", ".pawn" };
PUSHSTK_I(fline);
inpfname=duplicatestring(name);/* set name of include file */
if (inpfname==NULL)
error(103); /* insufficient memory */
inpf=fp; /* set input file pointer to include file */
error(103); /* insufficient memory */
inpf=fp; /* set input file pointer to include file */
fnumber++;
fline=0; /* set current line number to 0 */
fline=0; /* set current line number to 0 */
fcurrent=fnumber;
icomment=0; /* not in a comment */
insert_dbgfile(inpfname);
setfiledirect(inpfname);
listline=-1; /* force a #line directive when changing the file */
icomment=0; /* not in a comment */
insert_dbgfile(inpfname); /* attach to debug information */
insert_inputfile(inpfname); /* save for the error system */
assert(sc_status == statFIRST || strcmp(get_inputfile(fcurrent), inpfname) == 0);
setfiledirect(inpfname); /* (optionally) set in the list file */
listline=-1; /* force a #line directive when changing the file */
sc_is_utf8=(short)scan_utf8(inpf,name);
return TRUE;
}
@ -320,6 +322,7 @@ static void readline(unsigned char *line)
inpf=(FILE *)POPSTK_P();
insert_dbgfile(inpfname);
setfiledirect(inpfname);
assert(sc_status==statFIRST || strcmp(get_inputfile(fcurrent),inpfname)==0);
listline=-1; /* force a #line directive when changing the file */
} /* if */
@ -894,7 +897,7 @@ static int command(void)
assert(iflevel>=0);
if (iflevel==0) {
error(26); /* no matching #if */
errorset(sRESET);
errorset(sRESET,0);
} else {
/* check for earlier #else */
if ((ifstack[iflevel-1] & HANDLED_ELSE)==HANDLED_ELSE) {
@ -902,7 +905,7 @@ static int command(void)
error(61); /* #elseif directive may not follow an #else */
else
error(60); /* multiple #else directives between #if ... #endif */
errorset(sRESET);
errorset(sRESET,0);
} else {
assert(iflevel>0);
/* if there has been a "parse mode" on this level, set "skip mode",
@ -946,7 +949,7 @@ static int command(void)
ret=CMD_IF;
if (iflevel==0){
error(26); /* no matching "#if" */
errorset(sRESET);
errorset(sRESET,0);
} else {
iflevel--;
if (iflevel<skiplevel)
@ -1731,7 +1734,7 @@ SC_FUNC void preprocess(void)
lptr=pline; /* set "line pointer" to start of the parsing buffer */
iscommand=command();
if (iscommand!=CMD_NONE)
errorset(sRESET); /* reset error flag ("panic mode") on empty line or directive */
errorset(sRESET,0); /* reset error flag ("panic mode") on empty line or directive */
#if !defined NO_DEFINE
if (iscommand==CMD_NONE) {
assert(lptr!=term_expr);
@ -1925,7 +1928,7 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
while (i<=tLAST) { /* match reserved words and compiler directives */
if (*lptr==**tokptr && match(*tokptr,TRUE)) {
_lextok=i;
errorset(sRESET); /* reset error flag (clear the "panic mode")*/
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
if (pc_docexpr) /* optionally concatenate to documentation string */
insert_autolist(*tokptr);
return _lextok;
@ -2017,7 +2020,7 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
} else if (*lptr==';') { /* semicolumn resets "error" flag */
_lextok=';';
lptr+=1;
errorset(sRESET); /* reset error flag (clear the "panic mode")*/
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
} else {
_lextok=*lptr; /* if every match fails, return the character */
lptr+=1; /* increase the "lptr" pointer */
@ -2622,7 +2625,10 @@ SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom)
SC_FUNC void markusage(symbol *sym,int usage)
{
assert(sym!=NULL);
sym->usage |= (char)usage;
if ((usage & uWRITTEN) != 0)
sym->lnumber=fline;
/* check if (global) reference must be added to the symbol */
if ((usage & (uREAD | uWRITTEN))!=0) {
/* only do this for global symbols */
@ -2715,6 +2721,7 @@ SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,i
entry.compound=0; /* may be overridden later */
entry.states=NULL;
entry.fnumber=-1; /* assume global visibility (ignored for local symbols) */
entry.lnumber=fline;
entry.numrefers=1;
entry.refer=refer;
entry.parent=NULL;

View File

@ -51,7 +51,9 @@
static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */
static int errflag;
static int errfile;
static int errstart; /* line number at which the instruction started */
static int errline; /* forced line number for the error message */
/* error
*
@ -70,7 +72,7 @@ SC_FUNC int error(int number,...)
static char *prefix[3]={ "error", "fatal error", "warning" };
static int lastline,errorcount;
static short lastfile;
char *msg,*pre;
char *msg,*pre,*filename;
va_list argptr;
char string[128];
@ -107,11 +109,22 @@ static short lastfile;
strexpand(string,(unsigned char *)msg,sizeof string,SCPACK_TABLE);
assert(errstart<=fline);
if (errline>0)
errstart=errline; /* forced error position, set single line destination */
else
errline=fline; /* normal error, errstart may (or may not) have been marked, endpoint is current line */
if (errstart>errline)
errstart=errline; /* special case: error found at end of included file */
if (errfile>=0)
filename=get_inputfile(errfile);/* forced filename */
else
filename=inpfname; /* current file */
assert(filename!=NULL);
va_start(argptr,number);
if (strlen(errfname)==0) {
int start= (errstart==fline) ? -1 : errstart;
if (pc_error(number,string,inpfname,start,fline,argptr)) {
int start= (errstart==errline) ? -1 : errstart;
if (pc_error((int)number,string,filename,start,errline,argptr)) {
if (outf!=NULL) {
pc_closeasm(outf,TRUE);
outf=NULL;
@ -121,10 +134,10 @@ static short lastfile;
} else {
FILE *fp=fopen(errfname,"a");
if (fp!=NULL) {
if (errstart>=0 && errstart!=fline)
fprintf(fp,"%s(%d -- %d) : %s %03d: ",inpfname,errstart,fline,pre,number);
if (errstart>=0 && errstart!=errline)
fprintf(fp,"%s(%d -- %d) : %s %03d: ",filename,errstart,errline,pre,number);
else
fprintf(fp,"%s(%d) : %s %03d: ",inpfname,fline,pre,number);
fprintf(fp,"%s(%d) : %s %03d: ",filename,errline,pre,number);
vfprintf(fp,string,argptr);
fclose(fp);
} /* if */
@ -144,6 +157,8 @@ static short lastfile;
longjmp(errbuf,2); /* fatal error, quit */
} /* if */
errline=-1;
errfile=-1;
/* check whether we are seeing many errors on the same line */
if ((errstart<0 && lastline!=fline) || lastline<errstart || lastline>fline || fcurrent!=lastfile)
errorcount=0;
@ -157,7 +172,7 @@ static short lastfile;
return 0;
}
SC_FUNC void errorset(int code)
SC_FUNC void errorset(int code,int line)
{
switch (code) {
case sRESET:
@ -171,6 +186,15 @@ SC_FUNC void errorset(int code)
break;
case sEXPRRELEASE:
errstart=-1; /* forget start line number */
errline=-1;
errfile=-1;
break;
case sSETLINE:
errstart=-1; /* force error line number, forget start line */
errline=line;
break;
case sSETFILE:
errfile=line;
break;
} /* switch */
}

View File

@ -356,7 +356,7 @@ SC_FUNC void delete_substtable(void)
#endif /* !defined NO_SUBST */
/* ----- input file list ----------------------------------------- */
/* ----- input file list (explicit files)------------------------- */
static stringlist sourcefiles = {NULL, NULL};
SC_FUNC stringlist *insert_sourcefile(char *string)
@ -376,6 +376,28 @@ SC_FUNC void delete_sourcefiletable(void)
}
/* ----- parsed file list (explicit + included files) ------------ */
static stringlist inputfiles = {NULL, NULL};
SC_FUNC stringlist *insert_inputfile(char *string)
{
if (sc_status!=statFIRST)
return insert_string(&inputfiles,string);
return NULL;
}
SC_FUNC char *get_inputfile(int index)
{
return get_string(&inputfiles,index);
}
SC_FUNC void delete_inputfiletable(void)
{
delete_stringtable(&inputfiles);
assert(inputfiles.next==NULL);
}
/* ----- documentation tags -------------------------------------- */
#if !defined SC_LIGHT
static stringlist docstrings = {NULL, NULL};

View File

@ -14,7 +14,7 @@
#include <amxmodx>
#include <amxmisc>
#pragma tabsize 0
#pragma tabsize 4
new g_TeamOneAck[12];
new g_TeamTwoAck[12];