]> git.sur5r.net Git - cc65/blobdiff - src/ca65/symentry.c
Finished implemenation of commands to delete macros. Added the new commands to
[cc65] / src / ca65 / symentry.c
index 5d77696d1bd974def1dafd7fd762d112a48adc28..763820731c954d9d1d785877882256a1dd8df706 100644 (file)
@@ -2,14 +2,14 @@
 /*                                                                           */
 /*                               symentry.c                                 */
 /*                                                                           */
-/*         Symbol table entry forward for the ca65 macroassembler           */
+/*              Symbol table entry for the ca65 macroassembler               */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2007 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -37,6 +37,7 @@
 
 /* common */
 #include "addrsize.h"
+#include "symdefs.h"
 #include "xmalloc.h"
 
 /* ca65 */
@@ -72,7 +73,7 @@ SymEntry* SymLast = 0;
 
 
 
-SymEntry* NewSymEntry (const char* Name, unsigned Flags)
+SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
 /* Allocate a symbol table entry, initialize and return it */
 {
     unsigned I;
@@ -84,18 +85,21 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags)
     S->Left              = 0;
     S->Right             = 0;
     S->Locals            = 0;
-    S->SymTab            = 0;
-    S->Pos               = CurPos;
+    S->Sym.Tab    = 0;
+    S->LineInfos  = EmptyCollection;
+    GetFullLineInfo (&S->LineInfos, 1);
     for (I = 0; I < sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0]); ++I) {
         S->GuessedUse[I] = 0;
     }
     S->Flags             = Flags;
+    S->DebugSymId = ~0U;
+    S->ImportId   = ~0U;
     S->Expr       = 0;
     S->ExprRefs   = AUTO_COLLECTION_INITIALIZER;
     S->ExportSize = ADDR_SIZE_DEFAULT;
     S->AddrSize   = ADDR_SIZE_DEFAULT;
     memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
-    S->Name       = GetStringId (Name);
+    S->Name       = GetStrBufId (Name);
 
     /* Insert it into the list of all entries */
     S->List = SymList;
@@ -107,7 +111,7 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags)
 
 
 
-int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E)
+int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
 /* Search in the given tree for a name. If we find the symbol, the function
  * will return 0 and put the entry pointer into E. If we did not find the
  * symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
@@ -126,10 +130,10 @@ int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E)
     while (1) {
 
         /* Get the symbol name */
-        const char* SymName = GetString (T->Name);
+        const StrBuf* SymName = GetStrBuf (T->Name);
 
        /* Choose next entry */
-        int Cmp = strcmp (Name, SymName);
+        int Cmp = SB_Compare (Name, SymName);
                if (Cmp < 0 && T->Left) {
            T = T->Left;
        } else if (Cmp > 0&& T->Right) {
@@ -216,24 +220,24 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
 {
     if (S->Flags & SF_IMPORT) {
                /* Defined symbol is marked as imported external symbol */
-               Error ("Symbol `%s' is already an import", GetSymName (S));
+               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 */
-        Error ("Var symbol `%s' cannot be an export or global symbol", GetSymName (S));
+        Error ("Var symbol `%m%p' cannot be an export or global symbol", GetSymName (S));
         return;
     }
     if (S->Flags & SF_DEFINED) {
                /* Multiple definition. In case of a variable, this is legal. */
         if ((S->Flags & SF_VAR) == 0) {
-            Error ("Symbol `%s' is already defined", GetSymName (S));
+            Error ("Symbol `%m%p' is already defined", GetSymName (S));
             S->Flags |= SF_MULTDEF;
             return;
         } else {
             /* Redefinition must also be a variable symbol */
             if ((Flags & SF_VAR) == 0) {
-                Error ("Symbol `%s' is already different kind", GetSymName (S));
+                Error ("Symbol `%m%p' is already different kind", GetSymName (S));
                 return;
             }
             /* Delete the current symbol expression, since it will get
@@ -284,9 +288,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 */
-            PWarning (GetSymPos (S), 1, "Symbol `%s' is %s but exported %s",
-                      GetSymName (S), AddrSizeToStr (S->AddrSize),
-                      AddrSizeToStr (S->ExportSize));
+            LIWarning (&S->LineInfos, 1, "Symbol `%m%p' is %s but exported %s",
+                       GetSymName (S), AddrSizeToStr (S->AddrSize),
+                       AddrSizeToStr (S->ExportSize));
         }
     }
 
@@ -302,13 +306,13 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
 /* Mark the given symbol as an imported symbol */
 {
     if (S->Flags & SF_DEFINED) {
-       Error ("Symbol `%s' is already defined", GetSymName (S));
+       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 `%s'", GetSymName (S));
+       Error ("Cannot import exported symbol `%m%p'", GetSymName (S));
        return;
     }
 
@@ -324,16 +328,16 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
      */
     if (S->Flags & SF_IMPORT) {
        if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
-                   Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S));
+                   Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
        }
         if (AddrSize != S->AddrSize) {
-            Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+            Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
         }
     }
     if (S->Flags & SF_GLOBAL) {
         S->Flags &= ~SF_GLOBAL;
         if (AddrSize != S->AddrSize) {
-            Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+            Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
        }
     }
 
@@ -350,12 +354,12 @@ 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 `%s' is already an import", GetSymName (S));
+       Error ("Symbol `%m%p' is already an import", GetSymName (S));
        return;
     }
     if (S->Flags & SF_VAR) {
         /* Variable symbols cannot be exported */
-        Error ("Var symbol `%s' cannot be exported", GetSymName (S));
+        Error ("Var symbol `%m%p' cannot be exported", GetSymName (S));
         return;
     }
 
@@ -364,7 +368,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
      */
     if (S->Flags & SF_GLOBAL) {
         if (AddrSize != S->ExportSize) {
-            Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+            Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
         }
         S->Flags &= ~SF_GLOBAL;
     }
@@ -374,7 +378,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
      */
     if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) {
         if (S->ExportSize != AddrSize) {
-            Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+            Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
         }
     }
     S->ExportSize = AddrSize;
@@ -388,7 +392,7 @@ void SymExport (SymEntry* S, 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 */
-            Warning (1, "Symbol `%s' is %s but exported %s",
+            Warning (1, "Symbol `%m%p' is %s but exported %s",
                      GetSymName (S), AddrSizeToStr (S->AddrSize),
                      AddrSizeToStr (S->ExportSize));
         }
@@ -407,7 +411,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
 {
     if (S->Flags & SF_VAR) {
         /* Variable symbols cannot be exported or imported */
-        Error ("Var symbol `%s' cannot be made global", GetSymName (S));
+        Error ("Var symbol `%m%p' cannot be made global", GetSymName (S));
         return;
     }
 
@@ -420,7 +424,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
             AddrSize = GetCurrentSegAddrSize ();
         }
         if (AddrSize != S->AddrSize) {
-            Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+            Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
         }
         return;
     }
@@ -432,12 +436,12 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
         if ((S->Flags & SF_DEFINED) == 0) {
             /* Symbol is undefined */
             if (AddrSize != S->ExportSize) {
-                Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+                Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
             }
         } else if (AddrSize != ADDR_SIZE_DEFAULT) {
             /* Symbol is defined and address size given */
             if (AddrSize != S->ExportSize) {
-                Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+                Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
             }
         }
         return;
@@ -449,7 +453,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
      */
     if (S->Flags & SF_GLOBAL) {
         if (AddrSize != S->ExportSize) {
-            Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+            Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
         }
         return;
     }
@@ -467,7 +471,7 @@ void SymGlobal (SymEntry* S, 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 */
-            Warning (1, "Symbol `%s' is %s but exported %s",
+            Warning (1, "Symbol `%m%p' is %s but exported %s",
                      GetSymName (S), AddrSizeToStr (S->AddrSize),
                      AddrSizeToStr (S->ExportSize));
         }
@@ -505,12 +509,12 @@ 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 `%s' is already an import", GetSymName (S));
+               Error ("Symbol `%m%p' is already an import", GetSymName (S));
                return;
     }
     if (S->Flags & SF_VAR) {
         /* Variable symbols cannot be exported or imported */
-        Error ("Var symbol `%s' cannot be exported", GetSymName (S));
+        Error ("Var symbol `%m%p' cannot be exported", GetSymName (S));
         return;
     }
 
@@ -520,7 +524,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
      */
     if (S->Flags & (SF_EXPORT | SF_GLOBAL)) {
         if (S->ExportSize != AddrSize) {
-            Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+            Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
         }
         S->Flags &= ~SF_GLOBAL;
     }
@@ -534,7 +538,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
             /* Use the real size of the symbol */
             S->ExportSize = S->AddrSize;
         } else if (S->AddrSize != S->ExportSize) {
-            Error ("Address size mismatch for symbol `%s'", GetSymName (S));
+            Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
         }
     }
 
@@ -543,7 +547,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
      */
     if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
        if (S->ConDesPrio[Type] != Prio) {
-           Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S));
+           Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
        }
     }
     S->ConDesPrio[Type] = Prio;
@@ -575,7 +579,7 @@ void SymGuessedAddrSize (SymEntry* Sym, unsigned char AddrSize)
     }
 
     /* Ok, remember the file position */
-    Sym->GuessedUse[AddrSize-1] = xdup (&CurPos, sizeof (CurPos));
+    Sym->GuessedUse[AddrSize-1] = xdup (&CurTok.Pos, sizeof (CurTok.Pos));
 }
 
 
@@ -604,7 +608,7 @@ void SymImportFromGlobal (SymEntry* S)
 
 
 
-int SymIsConst (SymEntry* S, long* Val)
+int SymIsConst (const SymEntry* S, long* Val)
 /* Return true if the given symbol has a constant value. If Val is not NULL
  * and the symbol has a constant value, store it's value there.
  */
@@ -620,7 +624,18 @@ SymTable* GetSymParentScope (SymEntry* S)
  * NULL if the symbol is a cheap local, or defined on global level.
  */
 {
-    return (S->SymTab && S->SymTab->Parent)? S->SymTab->Parent : 0;
+    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;
+    }
 }
 
 
@@ -656,11 +671,39 @@ long GetSymVal (SymEntry* S)
 
 
 
-unsigned GetSymIndex (const SymEntry* S)
-/* Return the symbol index for the given symbol */
+unsigned GetSymImportId (const SymEntry* S)
+/* Return the import id for the given symbol */
+{
+    PRECONDITION (S != 0 && (S->Flags & SF_IMPORT) && S->ImportId != ~0U);
+    return S->ImportId;
+}
+
+
+
+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
+ * of the symbol. The result does not include the condes count.
+ * See common/symdefs.h for more information.
+ */
+{
+    /* Setup info flags */
+    unsigned Flags = 0;
+    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;
+
+    /* Return the result */
+    return Flags;
+}
+
+
+
+const FilePos* GetSymPos (const SymEntry* S)
+/* Return the position of first occurence in the source for the given symbol */
 {
-    PRECONDITION (S != 0 && (S->Flags & SF_INDEXED) != 0);
-    return S->Index;
+    /* The actual source entry is in slot zero */
+    return &((const LineInfo*) CollConstAt (&S->LineInfos, 0))->Pos;
 }