]> git.sur5r.net Git - cc65/blobdiff - src/cc65/symtab.c
Move default segment names into segnames.h
[cc65] / src / cc65 / symtab.c
index 45af446abaf708f5e765da1d529dad7ab30e0df6..2c50775d797ffe9e96eaa1993fcc71d5f0141596 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (C) 2000-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -40,6 +40,7 @@
 
 /* common */
 #include "check.h"
+#include "debugflag.h"
 #include "hashstr.h"
 #include "xmalloc.h"
 
@@ -81,9 +82,6 @@ SymTable      EmptySymTab = {
 #define SYMTAB_SIZE_STRUCT      19U
 #define SYMTAB_SIZE_LABEL        7U
 
-/* Predefined lexical levels */
-#define LEX_LEVEL_GLOBAL       1U
-
 /* The current and root symbol tables */
 static unsigned                LexicalLevel    = 0;    /* For safety checks */
 static SymTable*       SymTab0         = 0;
@@ -163,7 +161,7 @@ static void CheckSymTable (SymTable* Tab)
             * defined but not used.
             */
            if (((Flags & SC_AUTO) || (Flags & SC_STATIC)) && (Flags & SC_EXTERN) == 0) {
-               if ((Flags & SC_DEF) && !(Flags & SC_REF)) {
+               if (SymIsDef (Entry) && !SymIsRef (Entry)) {
                    if (Flags & SC_PARAM) {
                        Warning ("Parameter `%s' is never used", Entry->Name);
                    } else {
@@ -174,10 +172,10 @@ static void CheckSymTable (SymTable* Tab)
 
            /* If the entry is a label, check if it was defined in the function */
            if (Flags & SC_LABEL) {
-               if ((Flags & SC_DEF) == 0) {
+               if (!SymIsDef (Entry)) {
                    /* Undefined label */
-                   Error (ERR_UNDEFINED_LABEL, Entry->Name);
-               } else if ((Flags & SC_REF) == 0) {
+                   Error ("Undefined label: `%s'", Entry->Name);
+               } else if (!SymIsRef (Entry)) {
                    /* Defined but not used */
                    Warning ("`%s' is defined but never used", Entry->Name);
                }
@@ -198,6 +196,14 @@ static void CheckSymTable (SymTable* Tab)
 
 
 
+unsigned GetLexicalLevel (void)
+/* Return the current lexical level */
+{
+    return LexicalLevel;
+}
+
+
+
 void EnterGlobalLevel (void)
 /* Enter the program global lexical level */
 {
@@ -224,13 +230,13 @@ void LeaveGlobalLevel (void)
 
     /* Dump the tables if requested */
     if (Debug) {
-       PrintSymTable (SymTab0, stdout, "Global symbol table");
-       PrintSymTable (TagTab0, stdout, "Global tag table");
+       PrintSymTable (SymTab0, stdout, "Global symbol table");
+       PrintSymTable (TagTab0, stdout, "Global tag table");
     }
 
     /* Don't delete the symbol and struct tables! */
-    SymTab0 = SymTab = 0;
-    TagTab0 = TagTab = 0;
+    SymTab = 0;
+    TagTab = 0;
 }
 
 
@@ -441,6 +447,14 @@ SymEntry* FindSym (const char* Name)
 
 
 
+SymEntry* FindGlobalSym (const char* Name)
+/* Find the symbol with the given name in the global symbol table only */
+{
+    return FindSymInTable (SymTab0, Name, HashStr (Name));
+}
+
+
+
 SymEntry* FindLocalSym (const char* Name)
 /* Find the symbol with the given name in the current symbol table only */
 {
@@ -536,10 +550,10 @@ SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab)
        /* We do have an entry. This may be a forward, so check it. */
        if ((Entry->Flags & SC_STRUCT) == 0) {
            /* Existing symbol is not a struct */
-           Error (ERR_SYMBOL_KIND);
+           Error ("Symbol `%s' is already different kind", Name);
        } else if (Size > 0 && Entry->V.S.Size > 0) {
            /* Both structs are definitions. */
-           Error (ERR_MULTIPLE_DEFINITION, Name);
+           Error ("Multiple definition for `%s'", Name);
        } else {
            /* Define the struct size if it is given */
            if (Size > 0) {
@@ -567,28 +581,28 @@ SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab)
 
 
 
-SymEntry* AddEnumSym (const char* Name, int Val)
-/* Add an enum symbol to the symbol table and return it */
+SymEntry* AddConstSym (const char* Name, const type* Type, unsigned Flags, long Val)
+/* Add an constant symbol to the symbol table and return it */
 {
     /* Do we have an entry with this name already? */
     SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));
     if (Entry) {
-       if (Entry->Flags != SC_ENUM) {
-           Error (ERR_SYMBOL_KIND);
+       if ((Entry->Flags & SC_CONST) != SC_CONST) {
+           Error ("Symbol `%s' is already different kind", Name);
        } else {
-           Error (ERR_MULTIPLE_DEFINITION, Name);
+           Error ("Multiple definition for `%s'", Name);
        }
        return Entry;
     }
 
     /* Create a new entry */
-    Entry = NewSymEntry (Name, SC_ENUM);
+    Entry = NewSymEntry (Name, Flags);
 
     /* Enum values are ints */
-    Entry->Type        = TypeDup (type_int);
+    Entry->Type        = TypeDup (Type);
 
     /* Set the enum data */
-    Entry->V.EnumVal = Val;
+    Entry->V.ConstVal = Val;
 
     /* Add the entry to the symbol table */
     AddSymEntry (SymTab, Entry);
@@ -606,9 +620,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
     SymEntry* Entry = FindSymInTable (LabelTab, Name, HashStr (Name));
     if (Entry) {
 
-       if ((Entry->Flags & SC_DEF) != 0 && (Flags & SC_DEF) != 0) {
+       if (SymIsDef (Entry) && (Flags & SC_DEF) != 0) {
            /* Trying to define the label more than once */
-                   Error (ERR_MULTIPLE_DEFINITION, Name);
+                   Error ("Label `%s' is defined more than once", Name);
        }
        Entry->Flags |= Flags;
 
@@ -618,7 +632,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
        Entry = NewSymEntry (Name, SC_LABEL | Flags);
 
        /* Set a new label number */
-       Entry->V.Label = GetLabel ();
+       Entry->V.Label = GetLocalLabel ();
 
        /* Add the entry to the label table */
        AddSymEntry (LabelTab, Entry);
@@ -631,7 +645,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
 
 
 
-SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs)
+SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int Offs)
 /* Add a local symbol and return the symbol entry */
 {
     /* Do we have an entry with this name already? */
@@ -639,7 +653,7 @@ SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs)
     if (Entry) {
 
        /* We have a symbol with this name already */
-       Error (ERR_MULTIPLE_DEFINITION, Name);
+       Error ("Multiple definition for `%s'", Name);
 
     } else {
 
@@ -648,7 +662,18 @@ SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs)
 
        /* Set the symbol attributes */
        Entry->Type   = TypeDup (Type);
-       Entry->V.Offs = Offs;
+        if ((Flags & SC_AUTO) == SC_AUTO) {
+            Entry->V.Offs = Offs;
+        } else if ((Flags & SC_REGISTER) == SC_REGISTER) {
+            Entry->V.R.RegOffs  = Offs;
+            Entry->V.R.SaveOffs = oursp;        /* ### Cleaner! */
+        } else if ((Flags & SC_STATIC) == SC_STATIC) {
+            Entry->V.Label = Offs;
+        } else if ((Flags & SC_STRUCTFIELD) == SC_STRUCTFIELD) {
+            Entry->V.Offs = Offs;
+        } else {
+            Internal ("Invalid flags in AddLocalSym: %04X", Flags);
+        }
 
        /* Add the entry to the symbol table */
        AddSymEntry (SymTab, Entry);
@@ -661,11 +686,14 @@ SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs)
 
 
 
-SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
+SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
 /* Add an external or global symbol to the symbol table and return the entry */
 {
+    /* There is some special handling for functions, so check if it is one */
+    int IsFunc = IsTypeFunc (Type);
+
     /* Functions must be inserted in the global symbol table */
-    SymTable* Tab = IsTypeFunc (Type)? SymTab0 : SymTab;
+    SymTable* Tab = IsFunc? SymTab0 : SymTab;
 
     /* Do we have an entry with this name already? */
     SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
@@ -675,7 +703,7 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
 
        /* We have a symbol with this name already */
        if (Entry->Flags & SC_TYPE) {
-           Error (ERR_MULTIPLE_DEFINITION, Name);
+           Error ("Multiple definition for `%s'", Name);
            return Entry;
        }
 
@@ -689,16 +717,17 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
        if (IsTypeArray (Type) && IsTypeArray (EType)) {
 
            /* Get the array sizes */
-           unsigned Size  = Decode (Type + 1);
-           unsigned ESize = Decode (EType + 1);
+           long Size  = GetElementCount (Type);
+           long ESize = GetElementCount (EType);
 
-           if ((Size != 0 && ESize != 0) ||
+                   if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
                TypeCmp (Type+DECODE_SIZE+1, EType+DECODE_SIZE+1) < TC_EQUAL) {
                /* Types not identical: Conflicting types */
-               Error (ERR_CONFLICTING_TYPES, Name);
+               Error ("Conflicting types for `%s'", Name);
+               return Entry;
            } else {
                /* Check if we have a size in the existing definition */
-               if (ESize == 0) {
+               if (ESize == UNSPECIFIED) {                           
                    /* Existing, size not given, use size from new def */
                    Encode (EType + 1, Size);
                }
@@ -707,15 +736,20 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
                } else {
            /* New type must be identical */
            if (TypeCmp (EType, Type) < TC_EQUAL) {
-               Error (ERR_CONFLICTING_TYPES, Name);
+               Error ("Conflicting types for `%s'", Name);
+               return Entry;
            }
 
            /* In case of a function, use the new type descriptor, since it
             * contains pointers to the new symbol tables that are needed if
             * an actual function definition follows.
             */
-           if (IsTypeFunc (Type)) {
-               CopyEncode (Type+1, EType+1);
+           if (IsFunc) {
+               /* Get the function descriptor from the new type */
+               FuncDesc* F = GetFuncDesc (Type);
+               /* Use this new function descriptor */
+               Entry->V.F.Func = F;
+               EncodePtr (EType+1, F);
            }
        }
 
@@ -730,6 +764,14 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
        /* Set the symbol attributes */
        Entry->Type = TypeDup (Type);
 
+       /* If this is a function, set the function descriptor and clear
+        * additional fields.
+        */
+       if (IsFunc) {
+           Entry->V.F.Func = GetFuncDesc (Entry->Type);
+           Entry->V.F.Seg  = 0;
+       }
+
        /* Add the entry to the symbol table */
        AddSymEntry (Tab, Entry);
     }
@@ -754,6 +796,14 @@ SymTable* GetSymTab (void)
 
 
 
+SymTable* GetGlobalSymTab (void)
+/* Return the global symbol table */
+{
+    return SymTab0;
+}
+
+
+
 int SymIsLocal (SymEntry* Sym)
 /* Return true if the symbol is defined in the highest lexical level */
 {
@@ -772,7 +822,7 @@ void MakeZPSym (const char* Name)
     if (Entry) {
        Entry->Flags |= SC_ZEROPAGE;
     } else {
-       Error (ERR_UNDEFINED_SYMBOL, Name);
+       Error ("Undefined symbol: `%s'", Name);
     }
 }
 
@@ -818,17 +868,15 @@ void EmitExternals (void)
 {
     SymEntry* Entry;
 
-    AddEmptyLine ();
-
     Entry = SymTab->SymHead;
     while (Entry) {
        unsigned Flags = Entry->Flags;
                if (Flags & SC_EXTERN) {
            /* Only defined or referenced externs */
-           if ((Flags & SC_REF) != 0 && (Flags & SC_DEF) == 0) {
+           if (SymIsRef (Entry) && !SymIsDef (Entry)) {
                /* An import */
                g_defimport (Entry->Name, Flags & SC_ZEROPAGE);
-           } else if (Flags & SC_DEF) {
+           } else if (SymIsDef (Entry)) {
                /* An export */
                g_defexport (Entry->Name, Flags & SC_ZEROPAGE);
            }