]> git.sur5r.net Git - cc65/commitdiff
Remember where each symbol was defined and where it was referenced. Write this
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 18 Aug 2011 16:25:58 +0000 (16:25 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 18 Aug 2011 16:25:58 +0000 (16:25 +0000)
information to the object file.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5213 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/studyexpr.c
src/ca65/symentry.c
src/ca65/symentry.h
src/ca65/symtab.c

index 42a8dbbd6a748b513b53791aad8cc49a6ebc357c..b21f3b28bbc375b43a2648b14ee987eb77096295 100644 (file)
@@ -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);
index cb250478b0c03bb0a7a05ea1de68a04847df4e72..1b81f6a2b22d70292f11490290a74fb1c7841475 100644 (file)
@@ -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);
+    }
 }
 
 
index 2c098ad403c50b3a3071ed5217dd074a1f82996f..32fc183f6117a1fa6221cbecfdefc7ea03f97105 100644 (file)
@@ -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
index d76aad2efc74d0b125c65e1975a5e37f88a423ee..408c6daf675acff540e22f8ed2010c6019c530b7 100644 (file)
@@ -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;
        }