mirror of
https://github.com/cc65/cc65.git
synced 2025-01-11 11:30:13 +00:00
Use line infos to output more verbose error and warning messages whenever
possible. git-svn-id: svn://svn.cc65.org/cc65/trunk@4950 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
1dcba5c24e
commit
1072edb0d8
@ -84,7 +84,7 @@ static Assertion* NewAssertion (ExprNode* Expr, AssertAction Action, unsigned Ms
|
|||||||
A->Action = Action;
|
A->Action = Action;
|
||||||
A->Msg = Msg;
|
A->Msg = Msg;
|
||||||
A->LI = EmptyCollection;
|
A->LI = EmptyCollection;
|
||||||
GetFullLineInfo (&A->LI);
|
GetFullLineInfo (&A->LI, 1);
|
||||||
|
|
||||||
/* Return the new struct */
|
/* Return the new struct */
|
||||||
return A;
|
return A;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "instr.h"
|
#include "instr.h"
|
||||||
|
#include "lineinfo.h"
|
||||||
#include "nexttok.h"
|
#include "nexttok.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
@ -73,7 +74,7 @@ enum {
|
|||||||
typedef struct IfDesc IfDesc;
|
typedef struct IfDesc IfDesc;
|
||||||
struct IfDesc {
|
struct IfDesc {
|
||||||
unsigned Flags; /* Bitmapped flags, see above */
|
unsigned Flags; /* Bitmapped flags, see above */
|
||||||
FilePos Pos; /* File position of the .IF */
|
Collection LineInfos; /* File position of the .IF */
|
||||||
const char* Name; /* Name of the directive */
|
const char* Name; /* Name of the directive */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,9 +98,10 @@ static IfDesc* AllocIf (const char* Directive, int NeedTerm)
|
|||||||
ID = &IfStack [IfCount++];
|
ID = &IfStack [IfCount++];
|
||||||
|
|
||||||
/* Initialize elements */
|
/* Initialize elements */
|
||||||
ID->Flags = NeedTerm? ifNeedTerm : ifNone;
|
ID->Flags = NeedTerm? ifNeedTerm : ifNone;
|
||||||
ID->Pos = CurTok.Pos;
|
ID->LineInfos = EmptyCollection;
|
||||||
ID->Name = Directive;
|
GetFullLineInfo (&ID->LineInfos, 0);
|
||||||
|
ID->Name = Directive;
|
||||||
|
|
||||||
/* Return the result */
|
/* Return the result */
|
||||||
return ID;
|
return ID;
|
||||||
@ -218,7 +220,7 @@ void DoConditionals (void)
|
|||||||
/* Allow an .ELSE */
|
/* Allow an .ELSE */
|
||||||
InvertIfCond (D);
|
InvertIfCond (D);
|
||||||
SetElse (D, 1);
|
SetElse (D, 1);
|
||||||
D->Pos = CurTok.Pos;
|
GetFullLineInfo (&D->LineInfos, 0);
|
||||||
D->Name = ".ELSE";
|
D->Name = ".ELSE";
|
||||||
IfCond = GetCurrentIfCond ();
|
IfCond = GetCurrentIfCond ();
|
||||||
}
|
}
|
||||||
@ -464,6 +466,8 @@ void CheckOpenIfs (void)
|
|||||||
* open .ifs in this file.
|
* open .ifs in this file.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
const LineInfo* LI;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Get the current file number and check if the topmost entry on the
|
/* Get the current file number and check if the topmost entry on the
|
||||||
* .IF stack was inserted with this file number
|
* .IF stack was inserted with this file number
|
||||||
@ -474,13 +478,14 @@ void CheckOpenIfs (void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (D->Pos.Name != CurTok.Pos.Name) {
|
LI = CollConstAt (&D->LineInfos, 0);
|
||||||
|
if (LI->Pos.Name != CurTok.Pos.Name) {
|
||||||
/* The .if is from another file, bail out */
|
/* The .if is from another file, bail out */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start of .if is in the file we're about to leave */
|
/* Start of .if is in the file we're about to leave */
|
||||||
PError (&D->Pos, "Conditional assembly branch was never closed");
|
LIError (&D->LineInfos, "Conditional assembly branch was never closed");
|
||||||
FreeIf ();
|
FreeIf ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
172
src/ca65/error.c
172
src/ca65/error.c
@ -69,45 +69,49 @@ unsigned WarningCount = 0;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void FormatVMsg (StrBuf* S, const FilePos* Pos, const char* Desc,
|
static void VPrintMsg (const FilePos* Pos, const char* Desc,
|
||||||
const char* Format, va_list ap)
|
const char* Format, va_list ap)
|
||||||
/* Format an error/warning message into S. A trailing newline and a NUL
|
/* Format and output an error/warning message. */
|
||||||
* terminator will be added to S.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
|
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Format the actual message */
|
/* Format the actual message */
|
||||||
StrBuf Msg = STATIC_STRBUF_INITIALIZER;
|
StrBuf Msg = STATIC_STRBUF_INITIALIZER;
|
||||||
SB_VPrintf (&Msg, Format, ap);
|
SB_VPrintf (&Msg, Format, ap);
|
||||||
SB_Terminate (&Msg);
|
SB_Terminate (&Msg);
|
||||||
|
|
||||||
/* Format the message header */
|
/* Format the message header */
|
||||||
SB_Printf (S, "%s(%lu): %s: ",
|
SB_Printf (&S, "%s(%lu): %s: ",
|
||||||
SB_GetConstBuf (GetFileName (Pos->Name)),
|
SB_GetConstBuf (GetFileName (Pos->Name)),
|
||||||
Pos->Line,
|
Pos->Line,
|
||||||
Desc);
|
Desc);
|
||||||
|
|
||||||
/* Append the message to the message header */
|
/* Append the message to the message header */
|
||||||
SB_Append (S, &Msg);
|
SB_Append (&S, &Msg);
|
||||||
|
|
||||||
/* Delete the formatted message */
|
/* Delete the formatted message */
|
||||||
SB_Done (&Msg);
|
SB_Done (&Msg);
|
||||||
|
|
||||||
/* Add a new line and terminate the generated message */
|
/* Add a new line and terminate the generated full message */
|
||||||
SB_AppendChar (S, '\n');
|
SB_AppendChar (&S, '\n');
|
||||||
SB_Terminate (S);
|
SB_Terminate (&S);
|
||||||
|
|
||||||
|
/* Output the full message */
|
||||||
|
fputs (SB_GetConstBuf (&S), stderr);
|
||||||
|
|
||||||
|
/* Delete the buffer for the full message */
|
||||||
|
SB_Done (&S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void FormatMsg (StrBuf* S, const FilePos* Pos, const char* Desc,
|
static void PrintMsg (const FilePos* Pos, const char* Desc,
|
||||||
const char* Format, ...)
|
const char* Format, ...)
|
||||||
/* Format an error/warning message into S. A trailing newline and a NUL
|
/* Format and output an error/warning message. */
|
||||||
* terminator will be added to S.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
FormatVMsg (S, Pos, Desc, Format, ap);
|
VPrintMsg (Pos, Desc, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,8 +120,6 @@ static void FormatMsg (StrBuf* S, const FilePos* Pos, const char* Desc,
|
|||||||
static void AddNotifications (const Collection* LineInfos)
|
static void AddNotifications (const Collection* LineInfos)
|
||||||
/* Output additional notifications for an error or warning */
|
/* Output additional notifications for an error or warning */
|
||||||
{
|
{
|
||||||
StrBuf Msg = STATIC_STRBUF_INITIALIZER;
|
|
||||||
|
|
||||||
/* The basic line info is always in slot zero. It has been used to
|
/* The basic line info is always in slot zero. It has been used to
|
||||||
* output the actual error or warning. The following slots may contain
|
* output the actual error or warning. The following slots may contain
|
||||||
* more information. Check them and additional notifications if they're
|
* more information. Check them and additional notifications if they're
|
||||||
@ -130,38 +132,37 @@ static void AddNotifications (const Collection* LineInfos)
|
|||||||
/* Check the type and output an appropriate note */
|
/* Check the type and output an appropriate note */
|
||||||
unsigned Type = GetLineInfoType (LI);
|
unsigned Type = GetLineInfoType (LI);
|
||||||
if (Type == LI_TYPE_EXT) {
|
if (Type == LI_TYPE_EXT) {
|
||||||
FormatMsg (&Msg, GetSourcePos (LI), "Note",
|
PrintMsg (GetSourcePos (LI), "Note",
|
||||||
"Assembler code generated from this line");
|
"Assembler code generated from this line");
|
||||||
fputs (SB_GetConstBuf (&Msg), stderr);
|
|
||||||
|
|
||||||
} else if (Type == LI_TYPE_MACRO) {
|
} else if (Type == LI_TYPE_MACRO) {
|
||||||
|
PrintMsg (GetSourcePos (LI), "Note",
|
||||||
|
"Macro expansion was here");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SB_Done (&Msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Warnings */
|
/* Warnings */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void WarningMsg (const FilePos* Pos, unsigned Level, const char* Format, va_list ap)
|
static void WarningMsg (const Collection* LineInfos, const char* Format, va_list ap)
|
||||||
/* Print warning message. */
|
/* Print warning message. */
|
||||||
{
|
{
|
||||||
if (Level <= WarnLevel) {
|
/* The first entry in the collection is that of the actual source pos */
|
||||||
|
const LineInfo* LI = CollConstAt (LineInfos, 0);
|
||||||
|
|
||||||
StrBuf Msg = STATIC_STRBUF_INITIALIZER;
|
/* Output a warning for this position */
|
||||||
FormatVMsg (&Msg, Pos, "Warning", Format, ap);
|
VPrintMsg (GetSourcePos (LI), "Warning", Format, ap);
|
||||||
fputs (SB_GetConstBuf (&Msg), stderr);
|
|
||||||
SB_Done (&Msg);
|
|
||||||
|
|
||||||
++WarningCount;
|
/* Add additional notifications if necessary */
|
||||||
}
|
AddNotifications (LineInfos);
|
||||||
|
|
||||||
|
/* Count warnings */
|
||||||
|
++WarningCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -169,10 +170,22 @@ void WarningMsg (const FilePos* Pos, unsigned Level, const char* Format, va_list
|
|||||||
void Warning (unsigned Level, const char* Format, ...)
|
void Warning (unsigned Level, const char* Format, ...)
|
||||||
/* Print warning message. */
|
/* Print warning message. */
|
||||||
{
|
{
|
||||||
va_list ap;
|
if (Level <= WarnLevel) {
|
||||||
va_start (ap, Format);
|
|
||||||
WarningMsg (&CurTok.Pos, Level, Format, ap);
|
va_list ap;
|
||||||
va_end (ap);
|
Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
|
||||||
|
|
||||||
|
/* Get line infos for the current position */
|
||||||
|
GetFullLineInfo (&LineInfos, 0);
|
||||||
|
|
||||||
|
/* Output the message */
|
||||||
|
va_start (ap, Format);
|
||||||
|
WarningMsg (&LineInfos, Format, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
/* Free the line info list */
|
||||||
|
DoneCollection (&LineInfos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -180,10 +193,15 @@ void Warning (unsigned Level, const char* Format, ...)
|
|||||||
void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
|
void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
|
||||||
/* Print warning message giving an explicit file and position. */
|
/* Print warning message giving an explicit file and position. */
|
||||||
{
|
{
|
||||||
va_list ap;
|
if (Level <= WarnLevel) {
|
||||||
va_start (ap, Format);
|
va_list ap;
|
||||||
WarningMsg (Pos, Level, Format, ap);
|
va_start (ap, Format);
|
||||||
va_end (ap);
|
VPrintMsg (Pos, "Warning", Format, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
/* Count warnings */
|
||||||
|
++WarningCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -192,19 +210,11 @@ void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format,
|
|||||||
/* Print warning message using the given line infos */
|
/* Print warning message using the given line infos */
|
||||||
{
|
{
|
||||||
if (Level <= WarnLevel) {
|
if (Level <= WarnLevel) {
|
||||||
|
/* Output the message */
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
/* The first entry in the collection is that of the actual source pos */
|
|
||||||
const LineInfo* LI = CollConstAt (LineInfos, 0);
|
|
||||||
|
|
||||||
/* Output a warning for this position */
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
WarningMsg (GetSourcePos (LI), Level, Format, ap);
|
WarningMsg (LineInfos, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
/* Add additional notifications if necessary */
|
|
||||||
AddNotifications (LineInfos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,14 +226,19 @@ void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ErrorMsg (const FilePos* Pos, const char* Format, va_list ap)
|
void ErrorMsg (const Collection* LineInfos, const char* Format, va_list ap)
|
||||||
/* Print an error message */
|
/* Print an error message */
|
||||||
{
|
{
|
||||||
StrBuf Msg = STATIC_STRBUF_INITIALIZER;
|
/* The first entry in the collection is that of the actual source pos */
|
||||||
FormatVMsg (&Msg, Pos, "Error", Format, ap);
|
const LineInfo* LI = CollConstAt (LineInfos, 0);
|
||||||
fputs (SB_GetConstBuf (&Msg), stderr);
|
|
||||||
SB_Done (&Msg);
|
|
||||||
|
|
||||||
|
/* Output an error for this position */
|
||||||
|
VPrintMsg (GetSourcePos (LI), "Error", Format, ap);
|
||||||
|
|
||||||
|
/* Add additional notifications if necessary */
|
||||||
|
AddNotifications (LineInfos);
|
||||||
|
|
||||||
|
/* Count errors */
|
||||||
++ErrorCount;
|
++ErrorCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,20 +248,18 @@ void Error (const char* Format, ...)
|
|||||||
/* Print an error message */
|
/* Print an error message */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
|
||||||
|
|
||||||
|
/* Get line infos for the current position */
|
||||||
|
GetFullLineInfo (&LineInfos, 0);
|
||||||
|
|
||||||
|
/* Output the message */
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
ErrorMsg (&CurTok.Pos, Format, ap);
|
ErrorMsg (&LineInfos, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Free the line info list */
|
||||||
|
DoneCollection (&LineInfos);
|
||||||
void PError (const FilePos* Pos, const char* Format, ...)
|
|
||||||
/* Print an error message giving an explicit file and position. */
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start (ap, Format);
|
|
||||||
ErrorMsg (Pos, Format, ap);
|
|
||||||
va_end (ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -254,18 +267,11 @@ void PError (const FilePos* Pos, const char* Format, ...)
|
|||||||
void LIError (const Collection* LineInfos, const char* Format, ...)
|
void LIError (const Collection* LineInfos, const char* Format, ...)
|
||||||
/* Print an error message using the given line infos. */
|
/* Print an error message using the given line infos. */
|
||||||
{
|
{
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
/* The first entry in the collection is that of the actual source pos */
|
|
||||||
const LineInfo* LI = CollConstAt (LineInfos, 0);
|
|
||||||
|
|
||||||
/* Output an error for this position */
|
/* Output an error for this position */
|
||||||
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
ErrorMsg (GetSourcePos (LI), Format, ap);
|
ErrorMsg (LineInfos, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
/* Add additional notifications if necessary */
|
|
||||||
AddNotifications (LineInfos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -274,10 +280,20 @@ void ErrorSkip (const char* Format, ...)
|
|||||||
/* Print an error message and skip the rest of the line */
|
/* Print an error message and skip the rest of the line */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
|
||||||
|
|
||||||
|
/* Get line infos for the current position */
|
||||||
|
GetFullLineInfo (&LineInfos, 0);
|
||||||
|
|
||||||
|
/* Output the message */
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
ErrorMsg (&CurTok.Pos, Format, ap);
|
ErrorMsg (&LineInfos, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
|
/* Free the line info list */
|
||||||
|
DoneCollection (&LineInfos);
|
||||||
|
|
||||||
|
/* Skip tokens until we reach the end of the line */
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +78,6 @@ void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format,
|
|||||||
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
/* Print an error message */
|
/* Print an error message */
|
||||||
|
|
||||||
void PError (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3)));
|
|
||||||
/* Print an error message giving an explicit file and position. */
|
|
||||||
|
|
||||||
void LIError (const Collection* LineInfos, const char* Format, ...) attribute ((format (printf, 2, 3)));
|
void LIError (const Collection* LineInfos, const char* Format, ...) attribute ((format (printf, 2, 3)));
|
||||||
/* Print an error message using the given line infos. */
|
/* Print an error message using the given line infos. */
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ Fragment* NewFragment (unsigned char Type, unsigned short Len)
|
|||||||
F->Next = 0;
|
F->Next = 0;
|
||||||
F->LineList = 0;
|
F->LineList = 0;
|
||||||
F->LI = EmptyCollection;
|
F->LI = EmptyCollection;
|
||||||
GetFullLineInfo (&F->LI);
|
GetFullLineInfo (&F->LI, 1);
|
||||||
F->Len = Len;
|
F->Len = Len;
|
||||||
F->Type = Type;
|
F->Type = Type;
|
||||||
|
|
||||||
|
@ -94,29 +94,15 @@ static LineInfo* NewLineInfo (unsigned Type, const FilePos* Pos)
|
|||||||
LI->Index = INV_LINEINFO_INDEX;
|
LI->Index = INV_LINEINFO_INDEX;
|
||||||
LI->Pos = *Pos;
|
LI->Pos = *Pos;
|
||||||
|
|
||||||
|
/* Add the line info to the list of all line infos */
|
||||||
|
CollAppend (&LineInfoColl, LI);
|
||||||
|
|
||||||
/* Return the new struct */
|
/* Return the new struct */
|
||||||
return LI;
|
return LI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void FreeLineInfo (LineInfo* LI)
|
|
||||||
/* "Free" line info. If the usage counter is non zero, move it to the
|
|
||||||
* collection that contains all line infos, otherwise delete it.
|
|
||||||
* The function handles a NULL pointer transparently.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
if (LI) {
|
|
||||||
if (LI->Usage > 0) {
|
|
||||||
CollAppend (&LineInfoColl, LI);
|
|
||||||
} else {
|
|
||||||
xfree (LI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -128,6 +114,9 @@ void InitLineInfo (void)
|
|||||||
{
|
{
|
||||||
static const FilePos DefaultPos = STATIC_FILEPOS_INITIALIZER;
|
static const FilePos DefaultPos = STATIC_FILEPOS_INITIALIZER;
|
||||||
|
|
||||||
|
/* Increase the initial count of the line info collection */
|
||||||
|
CollGrow (&LineInfoColl, 200);
|
||||||
|
|
||||||
/* Allocate 8 slots */
|
/* Allocate 8 slots */
|
||||||
AllocatedSlots = 8;
|
AllocatedSlots = 8;
|
||||||
CurLineInfo = xmalloc (AllocatedSlots * sizeof (LineInfoSlot));
|
CurLineInfo = xmalloc (AllocatedSlots * sizeof (LineInfoSlot));
|
||||||
@ -177,7 +166,7 @@ void FreeLineInfoSlot (unsigned Slot)
|
|||||||
PRECONDITION (Slot == UsedSlots - 1);
|
PRECONDITION (Slot == UsedSlots - 1);
|
||||||
|
|
||||||
/* Free the last entry */
|
/* Free the last entry */
|
||||||
FreeLineInfo (CurLineInfo[Slot].Info);
|
CurLineInfo[Slot].Info = 0;
|
||||||
--UsedSlots;
|
--UsedSlots;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,19 +178,10 @@ void GenLineInfo (unsigned Slot, const FilePos* Pos)
|
|||||||
/* Get a pointer to the slot */
|
/* Get a pointer to the slot */
|
||||||
LineInfoSlot* S = CurLineInfo + Slot;
|
LineInfoSlot* S = CurLineInfo + Slot;
|
||||||
|
|
||||||
/* Check if we already have data */
|
/* Generate new data only if it is different from the existing. */
|
||||||
if (S->Info) {
|
if (S->Info && CompareFilePos (&S->Info->Pos, Pos) == 0) {
|
||||||
/* Generate new data only if it is different from the existing. */
|
/* Already there */
|
||||||
if (CompareFilePos (&S->Info->Pos, Pos) == 0) {
|
return;
|
||||||
/* Already there */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have data, but it's not identical. If it is in use, copy it to
|
|
||||||
* line info collection, otherwise delete it.
|
|
||||||
*/
|
|
||||||
FreeLineInfo (S->Info);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new data */
|
/* Allocate new data */
|
||||||
@ -213,33 +193,33 @@ void GenLineInfo (unsigned Slot, const FilePos* Pos)
|
|||||||
void ClearLineInfo (unsigned Slot)
|
void ClearLineInfo (unsigned Slot)
|
||||||
/* Clear the line info in the given slot */
|
/* Clear the line info in the given slot */
|
||||||
{
|
{
|
||||||
/* Get a pointer to the slot */
|
/* Zero the pointer */
|
||||||
LineInfoSlot* S = CurLineInfo + Slot;
|
CurLineInfo[Slot].Info = 0;
|
||||||
|
|
||||||
/* Free the struct and zero the pointer */
|
|
||||||
FreeLineInfo (S->Info);
|
|
||||||
S->Info = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GetFullLineInfo (Collection* LineInfos)
|
void GetFullLineInfo (Collection* LineInfos, unsigned IncUsage)
|
||||||
/* Return full line infos, that is line infos for all slots in LineInfos. The
|
/* Return full line infos, that is line infos for all slots in LineInfos. The
|
||||||
* function does also increase the usage counter for all line infos returned.
|
* function will clear LineInfos before usage and will increment the usage
|
||||||
|
* counter by IncUsage for all line infos returned.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
|
/* Clear the collection */
|
||||||
|
CollDeleteAll (LineInfos);
|
||||||
|
|
||||||
/* Copy all valid line infos to the collection */
|
/* Copy all valid line infos to the collection */
|
||||||
for (I = 0; I < UsedSlots; ++I) {
|
for (I = 0; I < UsedSlots; ++I) {
|
||||||
|
|
||||||
/* Get the slot */
|
/* Get the line info from the slot */
|
||||||
LineInfoSlot* S = CurLineInfo + I;
|
LineInfo* LI = CurLineInfo[I].Info;
|
||||||
|
|
||||||
/* Ignore empty slots */
|
/* Ignore empty slots */
|
||||||
if (S->Info) {
|
if (LI) {
|
||||||
++S->Info->Usage;
|
LI->Usage += IncUsage;
|
||||||
CollAppend (LineInfos, S->Info);
|
CollAppend (LineInfos, LI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -330,12 +310,7 @@ void MakeLineInfoIndex (void)
|
|||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
/* Be sure to move pending line infos to the global list */
|
/* Sort the line info list */
|
||||||
for (I = 0; I < UsedSlots; ++I) {
|
|
||||||
FreeLineInfo (CurLineInfo[I].Info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort the collection */
|
|
||||||
CollSort (&LineInfoColl, CmpLineInfo, 0);
|
CollSort (&LineInfoColl, CmpLineInfo, 0);
|
||||||
|
|
||||||
/* Walk over the list, index the line infos and count the used ones */
|
/* Walk over the list, index the line infos and count the used ones */
|
||||||
|
@ -107,9 +107,10 @@ void GenLineInfo (unsigned Slot, const FilePos* Pos);
|
|||||||
void ClearLineInfo (unsigned Slot);
|
void ClearLineInfo (unsigned Slot);
|
||||||
/* Clear the line info in the given slot */
|
/* Clear the line info in the given slot */
|
||||||
|
|
||||||
void GetFullLineInfo (Collection* LineInfos);
|
void GetFullLineInfo (Collection* LineInfos, unsigned IncUsage);
|
||||||
/* Return full line infos, that is line infos for all slots in LineInfos. The
|
/* Return full line infos, that is line infos for all slots in LineInfos. The
|
||||||
* function does also increase the usage counter for all line infos returned.
|
* function will clear LineInfos before usage and will increment the usage
|
||||||
|
* counter by IncUsage for all line infos returned.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LineInfo* UseLineInfo (LineInfo* LI);
|
LineInfo* UseLineInfo (LineInfo* LI);
|
||||||
|
@ -1103,12 +1103,14 @@ CharAgain:
|
|||||||
CurTok.Tok = TOK_DIV;
|
CurTok.Tok = TOK_DIV;
|
||||||
} else if (CComments) {
|
} else if (CComments) {
|
||||||
/* Remember the position, then skip the '*' */
|
/* Remember the position, then skip the '*' */
|
||||||
FilePos Pos = CurTok.Pos;
|
Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
|
||||||
|
GetFullLineInfo (&LineInfos, 0);
|
||||||
NextChar ();
|
NextChar ();
|
||||||
do {
|
do {
|
||||||
while (C != '*') {
|
while (C != '*') {
|
||||||
if (C == EOF) {
|
if (C == EOF) {
|
||||||
PError (&Pos, "Unterminated comment");
|
LIError (&LineInfos, "Unterminated comment");
|
||||||
|
DoneCollection (&LineInfos);
|
||||||
goto CharAgain;
|
goto CharAgain;
|
||||||
}
|
}
|
||||||
NextChar ();
|
NextChar ();
|
||||||
@ -1116,6 +1118,7 @@ CharAgain:
|
|||||||
NextChar ();
|
NextChar ();
|
||||||
} while (C != '/');
|
} while (C != '/');
|
||||||
NextChar ();
|
NextChar ();
|
||||||
|
DoneCollection (&LineInfos);
|
||||||
goto Again;
|
goto Again;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -510,9 +510,9 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
|
|||||||
if (Verbosity > 0) {
|
if (Verbosity > 0) {
|
||||||
DumpExpr (Expr, SymResolve);
|
DumpExpr (Expr, SymResolve);
|
||||||
}
|
}
|
||||||
PError (GetSymPos (Sym),
|
LIError (&Sym->LineInfos,
|
||||||
"Circular reference in definition of symbol `%m%p'",
|
"Circular reference in definition of symbol `%m%p'",
|
||||||
GetSymName (Sym));
|
GetSymName (Sym));
|
||||||
ED_Invalidate (D);
|
ED_Invalidate (D);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
|
|||||||
S->Locals = 0;
|
S->Locals = 0;
|
||||||
S->Sym.Tab = 0;
|
S->Sym.Tab = 0;
|
||||||
S->LineInfos = EmptyCollection;
|
S->LineInfos = EmptyCollection;
|
||||||
GetFullLineInfo (&S->LineInfos);
|
GetFullLineInfo (&S->LineInfos, 1);
|
||||||
for (I = 0; I < sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0]); ++I) {
|
for (I = 0; I < sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0]); ++I) {
|
||||||
S->GuessedUse[I] = 0;
|
S->GuessedUse[I] = 0;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ static ULabel* NewULabel (ExprNode* Val)
|
|||||||
|
|
||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
L->LineInfos = EmptyCollection;
|
L->LineInfos = EmptyCollection;
|
||||||
GetFullLineInfo (&L->LineInfos);
|
GetFullLineInfo (&L->LineInfos, 0);
|
||||||
L->Val = Val;
|
L->Val = Val;
|
||||||
L->Ref = 0;
|
L->Ref = 0;
|
||||||
|
|
||||||
@ -161,8 +161,7 @@ void ULabDef (void)
|
|||||||
ULabel* L = CollAtUnchecked (&ULabList, ULabDefCount);
|
ULabel* L = CollAtUnchecked (&ULabList, ULabDefCount);
|
||||||
CHECK (L->Val == 0);
|
CHECK (L->Val == 0);
|
||||||
L->Val = GenCurrentPC ();
|
L->Val = GenCurrentPC ();
|
||||||
CollDeleteAll (&L->LineInfos);
|
GetFullLineInfo (&L->LineInfos, 0);
|
||||||
GetFullLineInfo (&L->LineInfos);
|
|
||||||
} else {
|
} else {
|
||||||
/* There is no such label, create it */
|
/* There is no such label, create it */
|
||||||
NewULabel (GenCurrentPC ());
|
NewULabel (GenCurrentPC ());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user