Remember where each symbol was defined and where it was referenced. Write this
information to the object file. git-svn-id: svn://svn.cc65.org/cc65/trunk@5213 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -510,7 +510,7 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
|
|||||||
if (Verbosity > 0) {
|
if (Verbosity > 0) {
|
||||||
DumpExpr (Expr, SymResolve);
|
DumpExpr (Expr, SymResolve);
|
||||||
}
|
}
|
||||||
LIError (&Sym->LineInfos,
|
LIError (&Sym->DefLines,
|
||||||
"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);
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
|
|||||||
S->Right = 0;
|
S->Right = 0;
|
||||||
S->Locals = 0;
|
S->Locals = 0;
|
||||||
S->Sym.Tab = 0;
|
S->Sym.Tab = 0;
|
||||||
S->LineInfos = EmptyCollection;
|
S->DefLines = EmptyCollection;
|
||||||
GetFullLineInfo (&S->LineInfos);
|
S->RefLines = EmptyCollection;
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -149,15 +149,6 @@ int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SymRef (SymEntry* S)
|
|
||||||
/* Mark the given symbol as referenced */
|
|
||||||
{
|
|
||||||
/* Mark the symbol as referenced */
|
|
||||||
S->Flags |= SF_REFERENCED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SymTransferExprRefs (SymEntry* From, SymEntry* To)
|
void SymTransferExprRefs (SymEntry* From, SymEntry* To)
|
||||||
/* Transfer all expression references from one symbol to another. */
|
/* Transfer all expression references from one symbol to another. */
|
||||||
{
|
{
|
||||||
@@ -276,12 +267,16 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
|
|||||||
*/
|
*/
|
||||||
if (S->Flags & SF_GLOBAL) {
|
if (S->Flags & SF_GLOBAL) {
|
||||||
S->Flags = (S->Flags & ~SF_GLOBAL) | SF_EXPORT;
|
S->Flags = (S->Flags & ~SF_GLOBAL) | SF_EXPORT;
|
||||||
|
ReleaseFullLineInfo (&S->DefLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark the symbol as defined and use the given address size */
|
/* Mark the symbol as defined and use the given address size */
|
||||||
S->Flags |= (SF_DEFINED | Flags);
|
S->Flags |= (SF_DEFINED | Flags);
|
||||||
S->AddrSize = AddrSize;
|
S->AddrSize = AddrSize;
|
||||||
|
|
||||||
|
/* Remember the line info of the symbol definition */
|
||||||
|
GetFullLineInfo (&S->DefLines);
|
||||||
|
|
||||||
/* If the symbol is exported, check the address sizes */
|
/* If the symbol is exported, check the address sizes */
|
||||||
if (S->Flags & SF_EXPORT) {
|
if (S->Flags & SF_EXPORT) {
|
||||||
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
|
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
|
||||||
@@ -289,7 +284,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
|
|||||||
S->ExportSize = S->AddrSize;
|
S->ExportSize = S->AddrSize;
|
||||||
} else if (S->AddrSize > S->ExportSize) {
|
} else if (S->AddrSize > S->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
LIWarning (&S->LineInfos, 1, "Symbol `%m%p' is %s but exported %s",
|
Warning (1, "Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
||||||
AddrSizeToStr (S->ExportSize));
|
AddrSizeToStr (S->ExportSize));
|
||||||
}
|
}
|
||||||
@@ -303,6 +298,18 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SymRef (SymEntry* S)
|
||||||
|
/* Mark the given symbol as referenced */
|
||||||
|
{
|
||||||
|
/* Mark the symbol as referenced */
|
||||||
|
S->Flags |= SF_REFERENCED;
|
||||||
|
|
||||||
|
/* Remember the current location */
|
||||||
|
CollAppend (&S->RefLines, GetAsmLineInfo ());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
||||||
/* Mark the given symbol as an imported symbol */
|
/* Mark the given symbol as an imported symbol */
|
||||||
{
|
{
|
||||||
@@ -345,6 +352,12 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
/* Set the symbol data */
|
/* Set the symbol data */
|
||||||
S->Flags |= (SF_IMPORT | Flags);
|
S->Flags |= (SF_IMPORT | Flags);
|
||||||
S->AddrSize = AddrSize;
|
S->AddrSize = AddrSize;
|
||||||
|
|
||||||
|
/* Mark the position of the import as the position of the definition.
|
||||||
|
* Please note: In case of multiple .global or .import statements, the line
|
||||||
|
* infos add up.
|
||||||
|
*/
|
||||||
|
GetFullLineInfo (&S->DefLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -372,6 +385,11 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
S->Flags &= ~SF_GLOBAL;
|
S->Flags &= ~SF_GLOBAL;
|
||||||
|
|
||||||
|
/* .GLOBAL remembers line infos in case an .IMPORT follows. We have
|
||||||
|
* to remove these here.
|
||||||
|
*/
|
||||||
|
ReleaseFullLineInfo (&S->DefLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the symbol was already marked as an export, but wasn't defined
|
/* If the symbol was already marked as an export, but wasn't defined
|
||||||
@@ -489,6 +507,11 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
}
|
}
|
||||||
S->ExportSize = AddrSize;
|
S->ExportSize = AddrSize;
|
||||||
S->Flags |= (SF_GLOBAL | Flags);
|
S->Flags |= (SF_GLOBAL | Flags);
|
||||||
|
|
||||||
|
/* Remember the current location as location of definition in case
|
||||||
|
* an .IMPORT follows later.
|
||||||
|
*/
|
||||||
|
GetFullLineInfo (&S->DefLines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,6 +578,11 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
|
|||||||
|
|
||||||
/* Set the symbol data */
|
/* Set the symbol data */
|
||||||
S->Flags |= (SF_EXPORT | SF_REFERENCED);
|
S->Flags |= (SF_EXPORT | SF_REFERENCED);
|
||||||
|
|
||||||
|
/* In case we have no line info for the definition, record it now */
|
||||||
|
if (CollCount (&S->DefLines) == 0) {
|
||||||
|
GetFullLineInfo (&S->DefLines);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ struct SymEntry {
|
|||||||
struct SymTable* Tab; /* Table this symbol is in */
|
struct SymTable* Tab; /* Table this symbol is in */
|
||||||
struct SymEntry* Entry;
|
struct SymEntry* Entry;
|
||||||
} Sym;
|
} Sym;
|
||||||
Collection LineInfos; /* Line infos for this symbol */
|
Collection DefLines; /* Line infos for definition */
|
||||||
|
Collection RefLines; /* Line infos for references */
|
||||||
FilePos* GuessedUse[1]; /* File position where symbol
|
FilePos* GuessedUse[1]; /* File position where symbol
|
||||||
* address size was guessed, and the
|
* address size was guessed, and the
|
||||||
* smallest possible addressing was NOT
|
* smallest possible addressing was NOT
|
||||||
|
|||||||
@@ -470,7 +470,7 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
if (S->Flags & SF_EXPORT) {
|
if (S->Flags & SF_EXPORT) {
|
||||||
if (Sym->Flags & SF_IMPORT) {
|
if (Sym->Flags & SF_IMPORT) {
|
||||||
/* The symbol is already marked as import */
|
/* The symbol is already marked as import */
|
||||||
LIError (&S->LineInfos,
|
LIError (&S->RefLines,
|
||||||
"Symbol `%s' is already an import",
|
"Symbol `%s' is already an import",
|
||||||
GetString (Sym->Name));
|
GetString (Sym->Name));
|
||||||
}
|
}
|
||||||
@@ -478,7 +478,7 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
/* The symbol is already marked as an export. */
|
/* The symbol is already marked as an export. */
|
||||||
if (Sym->AddrSize > S->ExportSize) {
|
if (Sym->AddrSize > S->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
LIWarning (&S->LineInfos, 1,
|
LIWarning (&S->DefLines, 1,
|
||||||
"Symbol `%m%p' is %s but exported %s",
|
"Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (Sym),
|
GetSymName (Sym),
|
||||||
AddrSizeToStr (Sym->AddrSize),
|
AddrSizeToStr (Sym->AddrSize),
|
||||||
@@ -494,7 +494,7 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
}
|
}
|
||||||
if (Sym->AddrSize > Sym->ExportSize) {
|
if (Sym->AddrSize > Sym->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
LIWarning (&S->LineInfos, 1,
|
LIWarning (&S->DefLines, 1,
|
||||||
"Symbol `%m%p' is %s but exported %s",
|
"Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (Sym),
|
GetSymName (Sym),
|
||||||
AddrSizeToStr (Sym->AddrSize),
|
AddrSizeToStr (Sym->AddrSize),
|
||||||
@@ -502,7 +502,14 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Sym->Flags |= (S->Flags & SF_REFERENCED);
|
if (S->Flags & SF_REFERENCED) {
|
||||||
|
unsigned I;
|
||||||
|
Sym->Flags |= SF_REFERENCED;
|
||||||
|
for (I = 0; I < CollCount (&S->RefLines); ++I) {
|
||||||
|
CollAppend (&Sym->RefLines, CollAtUnchecked (&S->RefLines, I));
|
||||||
|
}
|
||||||
|
CollDeleteAll (&S->RefLines);
|
||||||
|
}
|
||||||
|
|
||||||
/* Transfer all expression references */
|
/* Transfer all expression references */
|
||||||
SymTransferExprRefs (S, Sym);
|
SymTransferExprRefs (S, Sym);
|
||||||
@@ -514,7 +521,7 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
/* The symbol is definitely undefined */
|
/* The symbol is definitely undefined */
|
||||||
if (S->Flags & SF_EXPORT) {
|
if (S->Flags & SF_EXPORT) {
|
||||||
/* We will not auto-import an export */
|
/* We will not auto-import an export */
|
||||||
LIError (&S->LineInfos,
|
LIError (&S->RefLines,
|
||||||
"Exported symbol `%m%p' was never defined",
|
"Exported symbol `%m%p' was never defined",
|
||||||
GetSymName (S));
|
GetSymName (S));
|
||||||
} else {
|
} else {
|
||||||
@@ -523,9 +530,11 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
S->Flags |= SF_IMPORT;
|
S->Flags |= SF_IMPORT;
|
||||||
/* Use the address size for code */
|
/* Use the address size for code */
|
||||||
S->AddrSize = CodeAddrSize;
|
S->AddrSize = CodeAddrSize;
|
||||||
|
/* Mark point of import */
|
||||||
|
GetFullLineInfo (&S->DefLines);
|
||||||
} else {
|
} else {
|
||||||
/* Error */
|
/* Error */
|
||||||
LIError (&S->LineInfos,
|
LIError (&S->RefLines,
|
||||||
"Symbol `%m%p' is undefined",
|
"Symbol `%m%p' is undefined",
|
||||||
GetSymName (S));
|
GetSymName (S));
|
||||||
}
|
}
|
||||||
@@ -564,6 +573,7 @@ void SymCheck (void)
|
|||||||
/* Handle undefined symbols */
|
/* Handle undefined symbols */
|
||||||
if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) {
|
if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) {
|
||||||
/* This is an undefined symbol. Handle it. */
|
/* This is an undefined symbol. Handle it. */
|
||||||
|
printf ("Undefined: %s\n", SB_GetConstBuf (GetSymName (S)));
|
||||||
SymCheckUndefined (S);
|
SymCheckUndefined (S);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,20 +592,21 @@ void SymCheck (void)
|
|||||||
(S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
|
(S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
|
||||||
|
|
||||||
/* Check for defined symbols that were never referenced */
|
/* Check for defined symbols that were never referenced */
|
||||||
if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
|
if (IsSizeOfSymbol (S)) {
|
||||||
const StrBuf* Name = GetStrBuf (S->Name);
|
/* Remove line infos, we don't need them any longer */
|
||||||
if (SB_At (Name, 0) != '.') { /* Ignore internals */
|
ReleaseFullLineInfo (&S->DefLines);
|
||||||
LIWarning (&S->LineInfos, 2,
|
ReleaseFullLineInfo (&S->RefLines);
|
||||||
|
} else if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
|
||||||
|
LIWarning (&S->DefLines, 2,
|
||||||
"Symbol `%m%p' is defined but never used",
|
"Symbol `%m%p' is defined but never used",
|
||||||
GetSymName (S));
|
GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign an index to all imports */
|
/* Assign an index to all imports */
|
||||||
if (S->Flags & SF_IMPORT) {
|
if (S->Flags & SF_IMPORT) {
|
||||||
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
|
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
|
||||||
/* Imported symbol is not referenced */
|
/* Imported symbol is not referenced */
|
||||||
LIWarning (&S->LineInfos, 2,
|
LIWarning (&S->DefLines, 2,
|
||||||
"Symbol `%m%p' is imported but never used",
|
"Symbol `%m%p' is imported but never used",
|
||||||
GetSymName (S));
|
GetSymName (S));
|
||||||
} else {
|
} else {
|
||||||
@@ -623,7 +634,7 @@ void SymCheck (void)
|
|||||||
S->ExportSize = S->AddrSize;
|
S->ExportSize = S->AddrSize;
|
||||||
} else if (S->AddrSize > S->ExportSize) {
|
} else if (S->AddrSize > S->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
LIWarning (&S->LineInfos, 1,
|
LIWarning (&S->DefLines, 1,
|
||||||
"Symbol `%m%p' is %s but exported %s",
|
"Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (S),
|
GetSymName (S),
|
||||||
AddrSizeToStr (S->AddrSize),
|
AddrSizeToStr (S->AddrSize),
|
||||||
@@ -707,7 +718,8 @@ void WriteImports (void)
|
|||||||
|
|
||||||
ObjWrite8 (S->AddrSize);
|
ObjWrite8 (S->AddrSize);
|
||||||
ObjWriteVar (S->Name);
|
ObjWriteVar (S->Name);
|
||||||
WriteLineInfo (&S->LineInfos);
|
WriteLineInfo (&S->DefLines);
|
||||||
|
WriteLineInfo (&S->RefLines);
|
||||||
}
|
}
|
||||||
S = S->List;
|
S = S->List;
|
||||||
}
|
}
|
||||||
@@ -787,7 +799,8 @@ void WriteExports (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write the line infos */
|
/* Write the line infos */
|
||||||
WriteLineInfo (&S->LineInfos);
|
WriteLineInfo (&S->DefLines);
|
||||||
|
WriteLineInfo (&S->RefLines);
|
||||||
}
|
}
|
||||||
S = S->List;
|
S = S->List;
|
||||||
}
|
}
|
||||||
@@ -884,7 +897,8 @@ void WriteDbgSyms (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write the line infos */
|
/* Write the line infos */
|
||||||
WriteLineInfo (&S->LineInfos);
|
WriteLineInfo (&S->DefLines);
|
||||||
|
WriteLineInfo (&S->RefLines);
|
||||||
}
|
}
|
||||||
S = S->List;
|
S = S->List;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user