]> git.sur5r.net Git - cc65/blobdiff - src/ca65/lineinfo.c
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / src / ca65 / lineinfo.c
index 7c8bf68fe698ba5ff8a499f971b78a2584cc61ae..dbc5b4d412c9de66846797ed7cfe855b5c002064 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                               lineinfo.c                                 */
+/*                                lineinfo.c                                 */
 /*                                                                           */
-/*                     Source file line info structure                      */
+/*                      Source file line info structure                      */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
@@ -33,6 +33,7 @@
 
 
 
+#include <stdio.h>
 #include <string.h>
 
 /* common */
@@ -41,6 +42,7 @@
 #include "xmalloc.h"
 
 /* ca65 */
+#include "filetab.h"
 #include "global.h"
 #include "lineinfo.h"
 #include "objfile.h"
@@ -70,7 +72,7 @@ static int HT_Compare (const void* Key1, const void* Key2);
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                   Data                                    */
 /*****************************************************************************/
 
 
@@ -79,8 +81,7 @@ static int HT_Compare (const void* Key1, const void* Key2);
 typedef struct LineInfoKey LineInfoKey;
 struct LineInfoKey {
     FilePos         Pos;                /* File position */
-    unsigned short  Type;               /* Type of line info */
-    unsigned short  Count;              /* Recursion counter */
+    unsigned        Type;               /* Type/count of line info */
 };
 
 /* Structure that holds line info */
@@ -88,8 +89,7 @@ struct LineInfo {
     HashNode        Node;               /* Hash table node */
     unsigned        Id;                 /* Index */
     LineInfoKey     Key;                /* Key for this line info */
-    unsigned char   Hashed;             /* True if in hash list */
-    unsigned char   Referenced;         /* Force reference even if no spans */
+    unsigned        RefCount;           /* Reference counter */
     Collection      Spans;              /* Segment spans for this line info */
     Collection      OpenSpans;          /* List of currently open spans */
 };
@@ -130,7 +130,7 @@ static unsigned HT_GenHash (const void* Key)
     const LineInfoKey* K = Key;
 
     /* Hash over a combination of type, file and line */
-    return HashInt ((K->Type << 18) ^ (K->Pos.Name << 14) ^ K->Pos.Line);
+    return HashInt ((K->Type << 21) ^ (K->Pos.Name << 14) ^ K->Pos.Line);
 }
 
 
@@ -153,15 +153,12 @@ static int HT_Compare (const void* Key1, const void* Key2)
     const LineInfoKey* K1 = Key1;
     const LineInfoKey* K2 = Key2;
 
-    /* Compare line number, then file and type, then count */
+    /* Compare line number, then file and type */
     int Res = (int)K2->Pos.Line - (int)K1->Pos.Line;
     if (Res == 0) {
         Res = (int)K2->Pos.Name - (int)K1->Pos.Name;
         if (Res == 0) {
             Res = (int)K2->Type - (int)K1->Type;
-            if (Res == 0) {
-                Res = (int)K2->Count - (int)K1->Count;
-            }
         }
     }
 
@@ -187,11 +184,13 @@ static LineInfo* NewLineInfo (const LineInfoKey* Key)
     InitHashNode (&LI->Node);
     LI->Id        = ~0U;
     LI->Key       = *Key;
-    LI->Hashed    = 0;
-    LI->Referenced= 0;
+    LI->RefCount  = 0;
     InitCollection (&LI->Spans);
     InitCollection (&LI->OpenSpans);
 
+    /* Add it to the hash table, so we will find it if necessary */
+    HT_Insert (&LineInfoTab, LI);
+
     /* Return the new struct */
     return LI;
 }
@@ -212,32 +211,58 @@ static void FreeLineInfo (LineInfo* LI)
 
 
 
-static void RememberLineInfo (LineInfo* LI)
-/* Remember a LineInfo by adding it to the hash table and the global list.
- * This will also assign the id which is actually the list position.
- */
+static int CheckLineInfo (void* Entry, void* Data attribute ((unused)))
+/* Called from HT_Walk. Remembers used line infos and assigns them an id */
 {
-    /* Assign the id */
-    LI->Id = CollCount (&LineInfoList);
-
-    /* Remember it in the global list */
-    CollAppend (&LineInfoList, LI);
-
-    /* Add it to the hash table, so we will find it if necessary */
-    HT_InsertEntry (&LineInfoTab, LI);
-
-    /* Remember that we have it */
-    LI->Hashed = 1;
+    /* Entry is actually a line info */
+    LineInfo* LI = Entry;
+
+    /* The entry is used if there are spans or the ref counter is non zero */
+    if (LI->RefCount > 0 || CollCount (&LI->Spans) > 0) {
+        LI->Id = CollCount (&LineInfoList);
+        CollAppend (&LineInfoList, LI);
+        return 0;       /* Keep the entry */
+    } else {
+        FreeLineInfo (LI);
+        return 1;       /* Remove entry from table */
+    }
 }
 
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
 
+#if 0
+static void DumpLineInfos (const char* Title, const Collection* C)
+/* Dump line infos from the given collection */
+{
+    unsigned I;
+    fprintf (stderr, "%s:\n", Title);
+    for (I = 0; I < CollCount (C); ++I) {
+        const LineInfo* LI = CollConstAt (C, I);
+        const char* Type;
+        switch (GetLineInfoType (LI)) {
+            case LI_TYPE_ASM:           Type = "ASM";           break;
+            case LI_TYPE_EXT:           Type = "EXT";           break;
+            case LI_TYPE_MACRO:         Type = "MACRO";         break;
+            case LI_TYPE_MACPARAM:      Type = "MACPARAM";      break;
+            default:                    Type = "unknown";       break;
+        }
+        fprintf (stderr,
+                 "%2u: %-8s %2u %-16s %u/%u\n",
+                 I, Type, LI->Key.Pos.Name,
+                 SB_GetConstBuf (GetFileName (LI->Key.Pos.Name)),
+                 LI->Key.Pos.Line, LI->Key.Pos.Col);
+    }
+}
+#endif
+
+
+
 void InitLineInfo (void)
 /* Initialize the line infos */
 {
@@ -262,6 +287,12 @@ void DoneLineInfo (void)
     while (Count) {
         EndLine (CollAt (&CurLineInfo, --Count));
     }
+
+    /* Walk over the entries in the hash table and sort them into used and
+     * unused ones. Add the used ones to the line info list and assign them
+     * an id.
+     */
+    HT_Walk (&LineInfoTab, CheckLineInfo, 0);
 }
 
 
@@ -269,35 +300,19 @@ void DoneLineInfo (void)
 void EndLine (LineInfo* LI)
 /* End a line that is tracked by the given LineInfo structure */
 {
-    unsigned I;
-
     /* Close the spans for the line */
-    CloseSpans (&LI->OpenSpans);
+    CloseSpanList (&LI->OpenSpans);
 
     /* Move the spans to the list of all spans for this line, then clear the
      * list of open spans.
      */
-    for (I = 0; I < CollCount (&LI->OpenSpans); ++I) {
-        CollAppend (&LI->Spans, CollAtUnchecked (&LI->OpenSpans, I));
-    }
+    CollTransfer (&LI->Spans, &LI->OpenSpans);
     CollDeleteAll (&LI->OpenSpans);
 
     /* Line info is no longer active - remove it from the list of current
      * line infos.
      */
     CollDeleteItem (&CurLineInfo, LI);
-
-    /* If this line info is already hashed, we're done. Otherwise, if it is
-     * marked as referenced or has non empty spans, remember it. It it is not
-     * referenced or doesn't have open spans, delete it.
-     */
-    if (!LI->Hashed) {
-        if (LI->Referenced || CollCount (&LI->Spans) > 0) {
-            RememberLineInfo (LI);
-        } else {
-            FreeLineInfo (LI);
-        }
-    }
 }
 
 
@@ -310,22 +325,19 @@ LineInfo* StartLine (const FilePos* Pos, unsigned Type, unsigned Count)
 
     /* Prepare the key struct */
     Key.Pos   = *Pos;
-    Key.Type  = Type;
-    Key.Count = Count;
+    Key.Type  = LI_MAKE_TYPE (Type, Count);
 
     /* Try to find a line info with this position and type in the hash table.
      * If so, reuse it. Otherwise create a new one.
      */
-    LI = HT_FindEntry (&LineInfoTab, &Key);
+    LI = HT_Find (&LineInfoTab, &Key);
     if (LI == 0) {
         /* Allocate a new LineInfo */
         LI = NewLineInfo (&Key);
-    } else {
-        Key.Count = 2;
     }
 
     /* Open the spans for this line info */
-    OpenSpans (&LI->OpenSpans);
+    OpenSpanList (&LI->OpenSpans);
 
     /* Add the line info to the list of current line infos */
     CollAppend (&CurLineInfo, LI);
@@ -360,36 +372,61 @@ void NewAsmLine (void)
 
 
 
-void GetFullLineInfo (Collection* LineInfos, int ForceRef)
+LineInfo* GetAsmLineInfo (void)
+/* Return the line info for the current assembler file. The function will
+ * bump the reference counter before returning the line info.
+ */
+{
+    ++AsmLineInfo->RefCount;
+    return AsmLineInfo;
+}
+
+
+
+void ReleaseLineInfo (LineInfo* LI)
+/* Decrease the reference count for a line info */
+{
+    /* Decrease the reference counter */
+    CHECK (LI->RefCount > 0);
+    ++LI->RefCount;
+}
+
+
+
+void GetFullLineInfo (Collection* LineInfos)
 /* Return full line infos, that is line infos for currently active Slots. The
- * function will clear LineInfos before usage. If ForceRef is not zero, a
- * forced reference will be added to all line infos, with the consequence that
- * they won't get deleted, even if there is no code or data generated for these
- * lines.
+ * infos will be added to the given collection, existing entries will be left
+ * intact. The reference count of all added entries will be increased.
  */
 {
     unsigned I;
 
-    /* Clear the collection */
-    CollDeleteAll (LineInfos);
+    /* Bum the reference counter for all active line infos */
+    for (I = 0; I < CollCount (&CurLineInfo); ++I) {
+        ++((LineInfo*)CollAt (&CurLineInfo, I))->RefCount;
+    }
 
-    /* Grow the collection as necessary */
-    CollGrow (LineInfos, CollCount (&CurLineInfo));
+    /* Copy all line infos over */
+    CollTransfer (LineInfos, &CurLineInfo);
+}
 
-    /* Copy all valid line infos to the collection */
-    for (I = 0; I < CollCount (&CurLineInfo); ++I) {
 
-        /* Get the line info from the slot */
-        LineInfo* LI = CollAt (&CurLineInfo, I);
 
-        /* Mark it as referenced */
-        if (ForceRef) {
-            LI->Referenced = 1;
-        }
+void ReleaseFullLineInfo (Collection* LineInfos)
+/* Decrease the reference count for a collection full of LineInfos, then clear
+ * the collection.
+ */
+{
+    unsigned I;
 
-        /* Return it to the caller */
-        CollAppend (LineInfos, LI);
+    /* Walk over all entries */
+    for (I = 0; I < CollCount (LineInfos); ++I) {
+        /* Release the the line info */
+        ReleaseLineInfo (CollAt (LineInfos, I));
     }
+
+    /* Delete all entries */
+    CollDeleteAll (LineInfos);
 }
 
 
@@ -424,6 +461,7 @@ void WriteLineInfo (const Collection* LineInfos)
         /* Get a pointer to the line info */
         const LineInfo* LI = CollConstAt (LineInfos, I);
 
+        /* Safety */
         CHECK (LI->Id != ~0U);
 
         /* Write the index to the file */
@@ -454,10 +492,10 @@ void WriteLineInfos (void)
         ObjWritePos (&LI->Key.Pos);
 
         /* Write the type and count of the line info */
-        ObjWriteVar (LI_MAKE_TYPE (LI->Key.Type, LI->Key.Count));
+        ObjWriteVar (LI->Key.Type);
 
-        /* Write the spans for this line */
-        WriteSpans (&LI->Spans);
+        /* Write the ids of the spans for this line */
+        WriteSpanList (&LI->Spans);
     }
 
     /* End of line infos */