]> git.sur5r.net Git - cc65/blobdiff - src/ca65/symentry.c
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / src / ca65 / symentry.c
index aebab7416d1441cf177779f353d7d964fd04ed81..612bc09f234c189845c080754195da9591a392fc 100644 (file)
@@ -1,6 +1,6 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                               symentry.c                                 */
+/*                                symentry.c                                 */
 /*                                                                           */
 /*              Symbol table entry for the ca65 macroassembler               */
 /*                                                                           */
@@ -54,7 +54,7 @@
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                   Data                                    */
 /*****************************************************************************/
 
 
@@ -68,7 +68,7 @@ SymEntry* SymLast = 0;
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
@@ -82,18 +82,20 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
     SymEntry* S = xmalloc (sizeof (SymEntry));
 
     /* Initialize the entry */
-    S->Left              = 0;
-    S->Right             = 0;
-    S->Locals            = 0;
+    S->Left       = 0;
+    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;
     }
-    S->Flags             = Flags;
+    S->HLLSym     = 0;
+    S->Flags      = Flags;
     S->DebugSymId = ~0U;
     S->ImportId   = ~0U;
+    S->ExportId   = ~0U;
     S->Expr       = 0;
     S->ExprRefs   = AUTO_COLLECTION_INITIALIZER;
     S->ExportSize = ADDR_SIZE_DEFAULT;
@@ -122,8 +124,8 @@ int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
 {
     /* Is there a tree? */
     if (T == 0) {
-       *E = 0;
-       return 1;
+        *E = 0;
+        return 1;
     }
 
     /* We have a table, search it */
@@ -132,31 +134,22 @@ int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
         /* Get the symbol name */
         const StrBuf* SymName = GetStrBuf (T->Name);
 
-       /* Choose next entry */
+        /* Choose next entry */
         int Cmp = SB_Compare (Name, SymName);
-               if (Cmp < 0 && T->Left) {
-           T = T->Left;
-       } else if (Cmp > 0&& T->Right) {
-           T = T->Right;
-       } else {
-           /* Found or end of search, return the result */
+        if (Cmp < 0 && T->Left) {
+            T = T->Left;
+        } else if (Cmp > 0 && T->Right) {
+            T = T->Right;
+        } else {
+            /* Found or end of search, return the result */
             *E = T;
             return Cmp;
-               }
+        }
     }
 }
 
 
 
-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. */
 {
@@ -219,9 +212,9 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
 /* Define a new symbol */
 {
     if (S->Flags & SF_IMPORT) {
-               /* Defined symbol is marked as imported external symbol */
-               Error ("Symbol `%m%p' is already an import", GetSymName (S));
-               return;
+        /* Defined symbol is marked as imported external symbol */
+        Error ("Symbol `%m%p' is already an import", GetSymName (S));
+        return;
     }
     if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) {
         /* Variable symbols cannot be exports or globals */
@@ -229,7 +222,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
         return;
     }
     if (S->Flags & SF_DEFINED) {
-               /* Multiple definition. In case of a variable, this is legal. */
+        /* Multiple definition. In case of a variable, this is legal. */
         if ((S->Flags & SF_VAR) == 0) {
             Error ("Symbol `%m%p' is already defined", GetSymName (S));
             S->Flags |= SF_MULTDEF;
@@ -275,12 +268,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) {
@@ -288,32 +285,44 @@ 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 */
-            PWarning (GetSymPos (S), 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));
         }
     }
 
     /* If this is not a local symbol, remember it as the last global one */
     if ((S->Flags & SF_LOCAL) == 0) {
-               SymLast = S;
+        SymLast = S;
     }
 }
 
 
 
+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 */
 {
     if (S->Flags & SF_DEFINED) {
-       Error ("Symbol `%m%p' is already defined", GetSymName (S));
-       S->Flags |= SF_MULTDEF;
-       return;
+        Error ("Symbol `%m%p' is already defined", GetSymName (S));
+        S->Flags |= SF_MULTDEF;
+        return;
     }
     if (S->Flags & SF_EXPORT) {
-       /* The symbol is already marked as exported symbol */
-       Error ("Cannot import exported symbol `%m%p'", GetSymName (S));
-       return;
+        /* The symbol is already marked as exported symbol */
+        Error ("Cannot import exported symbol `%m%p'", GetSymName (S));
+        return;
     }
 
     /* If no address size is given, use the address size of the enclosing
@@ -327,9 +336,9 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
      * then do silently remove the global flag.
      */
     if (S->Flags & SF_IMPORT) {
-       if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
-                   Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
-       }
+        if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
+            Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
+        }
         if (AddrSize != S->AddrSize) {
             Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
         }
@@ -338,12 +347,18 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
         S->Flags &= ~SF_GLOBAL;
         if (AddrSize != S->AddrSize) {
             Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
-       }
+        }
     }
 
     /* 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);
 }
 
 
@@ -353,9 +368,9 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
 {
     /* Check if it's ok to export the symbol */
     if (S->Flags & SF_IMPORT) {
-       /* The symbol is already marked as imported external symbol */
-       Error ("Symbol `%m%p' is already an import", GetSymName (S));
-       return;
+        /* The symbol is already marked as imported external symbol */
+        Error ("Symbol `%m%p' is already an import", GetSymName (S));
+        return;
     }
     if (S->Flags & SF_VAR) {
         /* Variable symbols cannot be exported */
@@ -371,6 +386,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
@@ -400,6 +420,9 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
 
     /* Set the symbol data */
     S->Flags |= (SF_EXPORT | SF_REFERENCED | Flags);
+
+    /* Remember line info for this reference */
+    CollAppend (&S->RefLines, GetAsmLineInfo ());
 }
 
 
@@ -488,6 +511,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);
     }
 }
 
@@ -508,9 +536,9 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
 
     /* Check for errors */
     if (S->Flags & SF_IMPORT) {
-               /* The symbol is already marked as imported external symbol */
-               Error ("Symbol `%m%p' is already an import", GetSymName (S));
-               return;
+        /* The symbol is already marked as imported external symbol */
+        Error ("Symbol `%m%p' is already an import", GetSymName (S));
+        return;
     }
     if (S->Flags & SF_VAR) {
         /* Variable symbols cannot be exported or imported */
@@ -546,14 +574,19 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
      * priority value is the same as the old one.
      */
     if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
-       if (S->ConDesPrio[Type] != Prio) {
-           Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
-       }
+        if (S->ConDesPrio[Type] != Prio) {
+            Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
+        }
     }
     S->ConDesPrio[Type] = Prio;
 
     /* 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);
+    }
 }
 
 
@@ -627,6 +660,11 @@ SymTable* GetSymParentScope (SymEntry* S)
     if ((S->Flags & SF_LOCAL) != 0) {
         /* This is a cheap local symbol */
         return 0;
+    } else if (S->Sym.Tab == 0) {
+        /* Symbol not in a table. This may happen if there have been errors
+         * before. Return NULL in this case to avoid further errors.
+         */
+        return 0;
     } else {
         /* This is a global symbol */
         return S->Sym.Tab->Parent;
@@ -675,6 +713,15 @@ unsigned GetSymImportId (const SymEntry* S)
 
 
 
+unsigned GetSymExportId (const SymEntry* S)
+/* Return the export id for the given symbol */
+{
+    PRECONDITION (S != 0 && (S->Flags & SF_EXPORT) && S->ExportId != ~0U);
+    return S->ExportId;
+}
+
+
+
 unsigned GetSymInfoFlags (const SymEntry* S, long* ConstVal)
 /* Return a set of flags used when writing symbol information into a file.
  * If the SYM_CONST bit is set, ConstVal will contain the constant value
@@ -687,6 +734,12 @@ unsigned GetSymInfoFlags (const SymEntry* S, long* ConstVal)
     Flags |= SymIsConst (S, ConstVal)? SYM_CONST : SYM_EXPR;
     Flags |= (S->Flags & SF_LABEL)? SYM_LABEL : SYM_EQUATE;
     Flags |= (S->Flags & SF_LOCAL)? SYM_CHEAP_LOCAL : SYM_STD;
+    if (S->Flags & SF_EXPORT) {
+        Flags |= SYM_EXPORT;
+    }
+    if (S->Flags & SF_IMPORT) {
+        Flags |= SYM_IMPORT;
+    }
 
     /* Return the result */
     return Flags;
@@ -694,12 +747,3 @@ unsigned GetSymInfoFlags (const SymEntry* S, long* ConstVal)
 
 
 
-const FilePos* GetSymPos (const SymEntry* S)
-/* Return the position of first occurence in the source for the given symbol */
-{
-    /* The actual source entry is in slot zero */
-    return &((const LineInfo*) CollConstAt (&S->LineInfos, 0))->Pos;
-}
-
-
-