From c52916f461f5f723bc8f2146e346dcb2de3b2f18 Mon Sep 17 00:00:00 2001 From: uz Date: Thu, 18 Aug 2011 16:25:58 +0000 Subject: [PATCH] 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 --- src/ca65/studyexpr.c | 2 +- src/ca65/symentry.c | 56 +++++++++++++++++++++++++++++++++----------- src/ca65/symentry.h | 3 ++- src/ca65/symtab.c | 52 +++++++++++++++++++++++++--------------- 4 files changed, 78 insertions(+), 35 deletions(-) diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 42a8dbbd6..b21f3b28b 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -510,7 +510,7 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D) if (Verbosity > 0) { DumpExpr (Expr, SymResolve); } - LIError (&Sym->LineInfos, + LIError (&Sym->DefLines, "Circular reference in definition of symbol `%m%p'", GetSymName (Sym)); ED_Invalidate (D); diff --git a/src/ca65/symentry.c b/src/ca65/symentry.c index cb250478b..1b81f6a2b 100644 --- a/src/ca65/symentry.c +++ b/src/ca65/symentry.c @@ -86,8 +86,8 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags) S->Right = 0; S->Locals = 0; S->Sym.Tab = 0; - S->LineInfos = EmptyCollection; - GetFullLineInfo (&S->LineInfos); + S->DefLines = EmptyCollection; + S->RefLines = EmptyCollection; for (I = 0; I < sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0]); ++I) { 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) /* 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) { S->Flags = (S->Flags & ~SF_GLOBAL) | SF_EXPORT; + ReleaseFullLineInfo (&S->DefLines); } /* Mark the symbol as defined and use the given address size */ S->Flags |= (SF_DEFINED | Flags); S->AddrSize = AddrSize; + /* Remember the line info of the symbol definition */ + GetFullLineInfo (&S->DefLines); + /* If the symbol is exported, check the address sizes */ if (S->Flags & SF_EXPORT) { if (S->ExportSize == ADDR_SIZE_DEFAULT) { @@ -289,9 +284,9 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags S->ExportSize = S->AddrSize; } else if (S->AddrSize > S->ExportSize) { /* We're exporting a symbol smaller than it actually is */ - LIWarning (&S->LineInfos, 1, "Symbol `%m%p' is %s but exported %s", - GetSymName (S), AddrSizeToStr (S->AddrSize), - AddrSizeToStr (S->ExportSize)); + Warning (1, "Symbol `%m%p' is %s but exported %s", + GetSymName (S), AddrSizeToStr (S->AddrSize), + 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) /* 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 */ S->Flags |= (SF_IMPORT | Flags); 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)); } 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 @@ -489,6 +507,11 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags) } S->ExportSize = AddrSize; 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 */ 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); + } } diff --git a/src/ca65/symentry.h b/src/ca65/symentry.h index 2c098ad40..32fc183f6 100644 --- a/src/ca65/symentry.h +++ b/src/ca65/symentry.h @@ -89,7 +89,8 @@ struct SymEntry { struct SymTable* Tab; /* Table this symbol is in */ struct SymEntry* Entry; } 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 * address size was guessed, and the * smallest possible addressing was NOT diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index d76aad2ef..408c6daf6 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -470,7 +470,7 @@ static void SymCheckUndefined (SymEntry* S) if (S->Flags & SF_EXPORT) { if (Sym->Flags & SF_IMPORT) { /* The symbol is already marked as import */ - LIError (&S->LineInfos, + LIError (&S->RefLines, "Symbol `%s' is already an import", GetString (Sym->Name)); } @@ -478,7 +478,7 @@ static void SymCheckUndefined (SymEntry* S) /* The symbol is already marked as an export. */ if (Sym->AddrSize > S->ExportSize) { /* 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", GetSymName (Sym), AddrSizeToStr (Sym->AddrSize), @@ -494,7 +494,7 @@ static void SymCheckUndefined (SymEntry* S) } if (Sym->AddrSize > Sym->ExportSize) { /* 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", GetSymName (Sym), 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 */ SymTransferExprRefs (S, Sym); @@ -514,7 +521,7 @@ static void SymCheckUndefined (SymEntry* S) /* The symbol is definitely undefined */ if (S->Flags & SF_EXPORT) { /* We will not auto-import an export */ - LIError (&S->LineInfos, + LIError (&S->RefLines, "Exported symbol `%m%p' was never defined", GetSymName (S)); } else { @@ -523,9 +530,11 @@ static void SymCheckUndefined (SymEntry* S) S->Flags |= SF_IMPORT; /* Use the address size for code */ S->AddrSize = CodeAddrSize; + /* Mark point of import */ + GetFullLineInfo (&S->DefLines); } else { /* Error */ - LIError (&S->LineInfos, + LIError (&S->RefLines, "Symbol `%m%p' is undefined", GetSymName (S)); } @@ -564,6 +573,7 @@ void SymCheck (void) /* Handle undefined symbols */ if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) { /* This is an undefined symbol. Handle it. */ + printf ("Undefined: %s\n", SB_GetConstBuf (GetSymName (S))); SymCheckUndefined (S); } @@ -582,20 +592,21 @@ void SymCheck (void) (S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) { /* Check for defined symbols that were never referenced */ - if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) { - const StrBuf* Name = GetStrBuf (S->Name); - if (SB_At (Name, 0) != '.') { /* Ignore internals */ - LIWarning (&S->LineInfos, 2, - "Symbol `%m%p' is defined but never used", - GetSymName (S)); - } - } + if (IsSizeOfSymbol (S)) { + /* Remove line infos, we don't need them any longer */ + ReleaseFullLineInfo (&S->DefLines); + 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", + GetSymName (S)); + } /* Assign an index to all imports */ if (S->Flags & SF_IMPORT) { if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) { /* Imported symbol is not referenced */ - LIWarning (&S->LineInfos, 2, + LIWarning (&S->DefLines, 2, "Symbol `%m%p' is imported but never used", GetSymName (S)); } else { @@ -623,7 +634,7 @@ void SymCheck (void) S->ExportSize = S->AddrSize; } else if (S->AddrSize > S->ExportSize) { /* 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", GetSymName (S), AddrSizeToStr (S->AddrSize), @@ -707,7 +718,8 @@ void WriteImports (void) ObjWrite8 (S->AddrSize); ObjWriteVar (S->Name); - WriteLineInfo (&S->LineInfos); + WriteLineInfo (&S->DefLines); + WriteLineInfo (&S->RefLines); } S = S->List; } @@ -787,7 +799,8 @@ void WriteExports (void) } /* Write the line infos */ - WriteLineInfo (&S->LineInfos); + WriteLineInfo (&S->DefLines); + WriteLineInfo (&S->RefLines); } S = S->List; } @@ -884,7 +897,8 @@ void WriteDbgSyms (void) } /* Write the line infos */ - WriteLineInfo (&S->LineInfos); + WriteLineInfo (&S->DefLines); + WriteLineInfo (&S->RefLines); } S = S->List; } -- 2.39.5