]> git.sur5r.net Git - cc65/blobdiff - src/cc65/symtab.c
Changed names of the pragmas to be identical to the corresponding command line
[cc65] / src / cc65 / symtab.c
index 28288df6c09635e3065f6855d51bd87f54f11cc6..dc246ef4b87f52d7b48c612490f0903cfea581a7 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (C) 2000-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 #include <stdarg.h>
 #include <string.h>
 
-#include "../common/hashstr.h"
-#include "../common/xmalloc.h"
+/* common */
+#include "check.h"
+#include "debugflag.h"
+#include "hashstr.h"
+#include "xmalloc.h"
 
+/* cc65 */
 #include "asmcode.h"
 #include "asmlabel.h"
-#include "check.h"
 #include "codegen.h"
 #include "datatype.h"
 #include "declare.h"
 #include "error.h"
 #include "funcdesc.h"
 #include "global.h"
+#include "stackptr.h"
 #include "symentry.h"
+#include "typecmp.h"
 #include "symtab.h"
 
 
@@ -78,9 +83,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;
@@ -154,29 +156,35 @@ static void CheckSymTable (SymTable* Tab)
        unsigned Flags = Entry->Flags;
 
        /* Ignore typedef entries */
-       if ((Flags & SC_TYPEDEF) != SC_TYPEDEF) {
+       if (!SymIsTypeDef (Entry)) {
 
            /* Check if the symbol is one with storage, and it if it was
             * 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 (WARN_UNUSED_PARM, Entry->Name);
+                        if (IS_Get (&WarnUnusedParam)) {
+                           Warning ("Parameter `%s' is never used", Entry->Name);
+                        }
                    } else {
-                       Warning (WARN_UNUSED_ITEM, Entry->Name);
+                        if (IS_Get (&WarnUnusedVar)) {
+                            Warning ("`%s' is defined but never used", Entry->Name);
+                        }
                    }
                }
            }
 
            /* 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) {
-                   /* Defined but not used */
-                   Warning (WARN_UNUSED_ITEM, Entry->Name);
+                   Error ("Undefined label: `%s'", Entry->Name);
+               } else if (!SymIsRef (Entry)) {
+                   /* Defined but not used */ 
+                    if (IS_Get (&WarnUnusedLabel)) {
+                       Warning ("`%s' is defined but never used", Entry->Name);
+                    }
                }
            }
 
@@ -195,6 +203,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 */
 {
@@ -221,13 +237,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;
 }
 
 
@@ -438,6 +454,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 */
 {
@@ -454,32 +478,27 @@ SymEntry* FindTagSym (const char* Name)
 
 
 
-SymEntry* FindStructField (const type* Type, const char* Name)
+SymEntry* FindStructField (const Type* T, const char* Name)
 /* Find a struct field in the fields list */
 {
     SymEntry* Field = 0;
 
     /* The given type may actually be a pointer to struct */
-    if (Type[0] == T_PTR) {
-       ++Type;
+    if (IsTypePtr (T)) {
+       ++T;
     }
 
     /* Non-structs do not have any struct fields... */
-    if (IsStruct (Type)) {
-
-       const SymTable* Tab;
+    if (IsClassStruct (T)) {
 
        /* Get a pointer to the struct/union type */
-       const SymEntry* Struct = (const SymEntry*) Decode (Type+1);
+       const SymEntry* Struct = GetSymEntry (T);
        CHECK (Struct != 0);
 
-       /* Get the field symbol table from the struct entry.
-        * Beware: The table may not exist.
+       /* Now search in the struct symbol table. Beware: The table may not
+         * exist.
         */
-       Tab = Struct->V.S.SymTab;
-
-       /* Now search in the struct symbol table */
-       if (Tab) {
+       if (Struct->V.S.SymTab) {
                    Field = FindSymInTable (Struct->V.S.SymTab, Name, HashStr (Name));
        }
     }
@@ -511,7 +530,7 @@ static void AddSymEntry (SymTable* T, SymEntry* S)
        /* First symbol */
        T->SymHead = S;
     }
-    T->SymCount++;
+    ++T->SymCount;
 
     /* Insert the symbol into the hash chain */
     S->NextHash  = T->Tab[Hash];
@@ -533,10 +552,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) {
@@ -564,31 +583,66 @@ 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* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned Width)
+/* Add a bit field to the local symbol table and return the symbol entry */
 {
     /* 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);
+
+       /* We have a symbol with this name already */
+       Error ("Multiple definition for `%s'", Name);
+
+    } else {
+
+       /* Create a new entry */
+       Entry = NewSymEntry (Name, SC_BITFIELD);
+
+       /* Set the symbol attributes. Bit-fields are always of type unsigned */
+       Entry->Type         = type_uint;
+        Entry->V.B.Offs     = Offs;
+        Entry->V.B.BitOffs  = BitOffs;
+        Entry->V.B.BitWidth = Width;
+
+       /* Add the entry to the symbol table */
+       AddSymEntry (SymTab, Entry);
+
+    }
+
+    /* Return the entry */
+    return Entry;
+}
+
+
+
+SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val)
+/* Add an constant symbol to the symbol table and return it */
+{
+    /* Enums must be inserted in the global symbol table */
+    SymTable* Tab = ((Flags & SC_ENUM) == SC_ENUM)? SymTab0 : SymTab;
+
+    /* Do we have an entry with this name already? */
+    SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
+    if (Entry) {
+       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 (T);
 
     /* Set the enum data */
-    Entry->V.EnumVal = Val;
+    Entry->V.ConstVal = Val;
 
     /* Add the entry to the symbol table */
-    AddSymEntry (SymTab, Entry);
+    AddSymEntry (Tab, Entry);
 
     /* Return the entry */
     return Entry;
@@ -603,9 +657,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;
 
@@ -615,7 +669,10 @@ 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 ();
+
+        /* Generate the assembler name of the label */
+        Entry->AsmName = xstrdup (LocalLabelName (Entry->V.Label));
 
        /* Add the entry to the label table */
        AddSymEntry (LabelTab, Entry);
@@ -628,25 +685,15 @@ 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* T, unsigned Flags, int Offs)
 /* Add a local symbol and return the symbol entry */
 {
-    SymEntry* Entry;
-
-    /* Functions declared inside of functions do always have external linkage */
-    if (Type != 0 && IsFunc (Type)) {
-               if ((Flags & (SC_DEFAULT | SC_EXTERN)) == 0) {
-                   Warning (WARN_FUNC_MUST_BE_EXTERN);
-               }
-               Flags = SC_EXTERN;
-    }
-
     /* Do we have an entry with this name already? */
-    Entry = FindSymInTable (SymTab, Name, HashStr (Name));
+    SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));
     if (Entry) {
 
        /* We have a symbol with this name already */
-       Error (ERR_MULTIPLE_DEFINITION, Name);
+       Error ("Multiple definition for `%s'", Name);
 
     } else {
 
@@ -654,8 +701,23 @@ SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs)
        Entry = NewSymEntry (Name, Flags);
 
        /* Set the symbol attributes */
-       Entry->Type   = TypeDup (Type);
-       Entry->V.Offs = Offs;
+       Entry->Type = TypeDup (T);
+        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 = StackPtr;
+        } else if ((Flags & SC_EXTERN) == SC_EXTERN) {
+            Entry->V.Label = Offs;
+        } else if ((Flags & SC_STATIC) == SC_STATIC) {
+            /* Generate the assembler name from the label number */
+            Entry->V.Label = Offs;
+            Entry->AsmName = xstrdup (LocalLabelName (Entry->V.Label));
+        } 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);
@@ -668,21 +730,24 @@ 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* T, 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 (T);
+
     /* Functions must be inserted in the global symbol table */
-    SymTable* Tab = IsFunc (Type)? SymTab0 : SymTab;
+    SymTable* Tab = IsFunc? SymTab0 : SymTab;
 
     /* Do we have an entry with this name already? */
     SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
     if (Entry) {
 
-       type* EType;
+       Type* EType;
 
        /* 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;
        }
 
@@ -693,36 +758,48 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
         * incomplete declaration. Accept this, and if the exsting entry is
         * incomplete, complete it.
         */
-       if (IsArray (Type) && IsArray (EType)) {
+       if (IsTypeArray (T) && IsTypeArray (EType)) {
 
            /* Get the array sizes */
-           unsigned Size  = Decode (Type + 1);
-           unsigned ESize = Decode (EType + 1);
-
-           if ((Size != 0 && ESize != 0) ||
-               TypeCmp (Type+DECODE_SIZE+1, EType+DECODE_SIZE+1) != 0) {
-               /* Types not identical: Duplicate definition */
-               Error (ERR_MULTIPLE_DEFINITION, Name);
+           long Size  = GetElementCount (T);
+           long ESize = GetElementCount (EType);
+
+                   if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
+               TypeCmp (T + 1, EType + 1) < TC_EQUAL) {
+               /* Types not identical: Conflicting types */
+               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);
+                   SetElementCount (EType, Size);
                }
            }
 
                } else {
            /* New type must be identical */
-           if (!EqualTypes (EType, Type) != 0) {
-               Error (ERR_MULTIPLE_DEFINITION, Name);
+           if (TypeCmp (EType, T) < TC_EQUAL) {
+               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.
+            * an actual function definition follows. Be sure not to use the
+             * new descriptor if it contains a function declaration with an
+             * empty parameter list.
             */
-           if (IsFunc (Type)) {
-               CopyEncode (Type+1, EType+1);
+           if (IsFunc) {
+               /* Get the function descriptor from the new type */
+               FuncDesc* F = GetFuncDesc (T);
+               /* Use this new function descriptor if it doesn't contain
+                 * an empty parameter list.
+                 */
+                if ((F->Flags & FD_EMPTY) == 0) {
+                    Entry->V.F.Func = F;
+                    SetFuncDesc (EType, F);
+                }
            }
        }
 
@@ -731,11 +808,27 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
 
     } else {
 
+        unsigned Len;
+
        /* Create a new entry */
        Entry = NewSymEntry (Name, Flags);
 
        /* Set the symbol attributes */
-       Entry->Type = TypeDup (Type);
+       Entry->Type = TypeDup (T);
+
+       /* 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 assembler name of the symbol */
+        Len = strlen (Name);
+        Entry->AsmName = xmalloc (Len + 2);
+        Entry->AsmName[0] = '_';
+        memcpy (Entry->AsmName+1, Name, Len+1);
 
        /* Add the entry to the symbol table */
        AddSymEntry (Tab, Entry);
@@ -761,156 +854,18 @@ SymTable* GetSymTab (void)
 
 
 
-int SymIsLocal (SymEntry* Sym)
-/* Return true if the symbol is defined in the highest lexical level */
-{
-    return (Sym->Owner == SymTab || Sym->Owner == TagTab);
-}
-
-
-
-static int EqualSymTables (SymTable* Tab1, SymTable* Tab2)
-/* Compare two symbol tables. Return 1 if they are equal and 0 otherwise */
+SymTable* GetGlobalSymTab (void)
+/* Return the global symbol table */
 {
-    /* Compare the parameter lists */
-    SymEntry* Sym1 = Tab1->SymHead;
-    SymEntry* Sym2 = Tab2->SymHead;
-
-    /* Compare the fields */
-    while (Sym1 && Sym2) {
-
-       /* Compare this field */
-       if (!EqualTypes (Sym1->Type, Sym2->Type)) {
-           /* Field types not equal */
-           return 0;
-       }
-
-       /* Get the pointers to the next fields */
-       Sym1 = Sym1->NextSym;
-       Sym2 = Sym2->NextSym;
-    }
-
-    /* Check both pointers against NULL to compare the field count */
-    return (Sym1 == 0 && Sym2 == 0);
+    return SymTab0;
 }
 
 
 
-int EqualTypes (const type* Type1, const type* Type2)
-/* Recursively compare two types. Return 1 if the types match, return 0
- * otherwise.
- */
+int SymIsLocal (SymEntry* Sym)
+/* Return true if the symbol is defined in the highest lexical level */
 {
-    int v1, v2;
-    SymEntry* Sym1;
-    SymEntry* Sym2;
-    SymTable* Tab1;
-    SymTable* Tab2;
-    FuncDesc* F1;
-    FuncDesc* F2;
-    int              Ok;
-
-
-    /* Shortcut here: If the pointers are identical, the types are identical */
-    if (Type1 == Type2) {
-       return 1;
-    }
-
-    /* Compare two types. Determine, where they differ */
-    while (*Type1 == *Type2 && *Type1 != T_END) {
-
-       switch (*Type1) {
-
-           case T_FUNC:
-               /* Compare the function descriptors */
-               F1 = DecodePtr (Type1+1);
-               F2 = DecodePtr (Type2+1);
-
-               /* If one of the functions is implicitly declared, both
-                * functions are considered equal. If one of the functions is
-                * old style, and the other is empty, the functions are
-                * considered equal.
-                */
-                       if ((F1->Flags & FD_IMPLICIT) != 0 || (F2->Flags & FD_IMPLICIT) != 0) {
-                   Ok = 1;
-               } else if ((F1->Flags & FD_OLDSTYLE) != 0 && (F2->Flags & FD_EMPTY) != 0) {
-                   Ok = 1;
-               } else if ((F1->Flags & FD_EMPTY) != 0 && (F2->Flags & FD_OLDSTYLE) != 0) {
-                   Ok = 1;
-               } else {
-                   Ok = 0;
-               }
-
-               if (!Ok) {
-
-                   /* Check the remaining flags */
-                   if ((F1->Flags & ~FD_IGNORE) != (F2->Flags & ~FD_IGNORE)) {
-                       /* Flags differ */
-                       return 0;
-                   }
-
-                   /* Compare the parameter lists */
-                   if (EqualSymTables (F1->SymTab, F2->SymTab) == 0 ||
-                       EqualSymTables (F1->TagTab, F2->TagTab) == 0) {
-                       /* One of the tables is not identical */
-                       return 0;
-                   }
-               }
-
-               /* Skip the FuncDesc pointers to compare the return type */
-               Type1 += DECODE_SIZE;
-               Type2 += DECODE_SIZE;
-               break;
-
-           case T_ARRAY:
-               /* Check member count */
-               v1 = Decode (Type1+1);
-               v2 = Decode (Type2+1);
-               if (v1 != 0 && v2 != 0 && v1 != v2) {
-                   /* Member count given but different */
-                   return 0;
-               }
-               Type1 += DECODE_SIZE;
-               Type2 += DECODE_SIZE;
-               break;
-
-           case T_STRUCT:
-           case T_UNION:
-                       /* Compare the fields recursively. To do that, we fetch the
-                * pointer to the struct definition from the type, and compare
-                * the fields.
-                */
-               Sym1 = DecodePtr (Type1+1);
-               Sym2 = DecodePtr (Type2+1);
-
-               /* Get the field tables from the struct entry */
-               Tab1 = Sym1->V.S.SymTab;
-               Tab2 = Sym2->V.S.SymTab;
-
-               /* One or both structs may be forward definitions. In this case,
-                * the symbol tables are both non existant. Assume that the
-                * structs are equal in this case.
-                */
-               if (Tab1 != 0 && Tab2 != 0) {
-
-                   if (EqualSymTables (Tab1, Tab2) == 0) {
-                       /* Field lists are not equal */
-                       return 0;
-                   }
-
-               }
-
-               /* Structs are equal */
-               Type1 += DECODE_SIZE;
-               Type2 += DECODE_SIZE;
-               break;
-       }
-       ++Type1;
-               ++Type2;
-    }
-
-    /* Done, types are equal */
-    return 1;
+    return (Sym->Owner == SymTab || Sym->Owner == TagTab);
 }
 
 
@@ -925,7 +880,7 @@ void MakeZPSym (const char* Name)
     if (Entry) {
        Entry->Flags |= SC_ZEROPAGE;
     } else {
-       Error (ERR_UNDEFINED_SYMBOL, Name);
+       Error ("Undefined symbol: `%s'", Name);
     }
 }
 
@@ -971,17 +926,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);
            }