]> 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 bbe26dff527691dae60b987683898f380b2452a2..dc246ef4b87f52d7b48c612490f0903cfea581a7 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2004 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (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       */
@@ -156,7 +156,7 @@ 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.
@@ -164,9 +164,13 @@ static void CheckSymTable (SymTable* Tab)
            if (((Flags & SC_AUTO) || (Flags & SC_STATIC)) && (Flags & SC_EXTERN) == 0) {
                if (SymIsDef (Entry) && !SymIsRef (Entry)) {
                    if (Flags & SC_PARAM) {
-                       Warning ("Parameter `%s' is never used", Entry->Name);
+                        if (IS_Get (&WarnUnusedParam)) {
+                           Warning ("Parameter `%s' is never used", Entry->Name);
+                        }
                    } else {
-                       Warning ("`%s' is defined but never used", Entry->Name);
+                        if (IS_Get (&WarnUnusedVar)) {
+                            Warning ("`%s' is defined but never used", Entry->Name);
+                        }
                    }
                }
            }
@@ -177,8 +181,10 @@ static void CheckSymTable (SymTable* Tab)
                    /* Undefined label */
                    Error ("Undefined label: `%s'", Entry->Name);
                } else if (!SymIsRef (Entry)) {
-                   /* Defined but not used */
-                   Warning ("`%s' is defined but never used", Entry->Name);
+                   /* Defined but not used */ 
+                    if (IS_Get (&WarnUnusedLabel)) {
+                       Warning ("`%s' is defined but never used", Entry->Name);
+                    }
                }
            }
 
@@ -472,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 (IsClassStruct (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));
        }
     }
@@ -582,7 +583,39 @@ SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab)
 
 
 
-SymEntry* AddConstSym (const char* Name, const type* Type, unsigned Flags, long Val)
+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) {
+
+       /* 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 */
@@ -603,7 +636,7 @@ SymEntry* AddConstSym (const char* Name, const type* Type, unsigned Flags, long
     Entry = NewSymEntry (Name, Flags);
 
     /* Enum values are ints */
-    Entry->Type        = TypeDup (Type);
+    Entry->Type        = TypeDup (T);
 
     /* Set the enum data */
     Entry->V.ConstVal = Val;
@@ -652,7 +685,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
 
 
 
-SymEntry* AddLocalSym (const char* Name, const 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 */
 {
     /* Do we have an entry with this name already? */
@@ -668,12 +701,14 @@ SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int O
        Entry = NewSymEntry (Name, Flags);
 
        /* Set the symbol attributes */
-       Entry->Type   = TypeDup (Type);
+       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;      
+            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;
@@ -695,11 +730,11 @@ SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int O
 
 
 
-SymEntry* AddGlobalSym (const char* Name, const 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 (Type);
+    int IsFunc = IsTypeFunc (T);
 
     /* Functions must be inserted in the global symbol table */
     SymTable* Tab = IsFunc? SymTab0 : SymTab;
@@ -708,7 +743,7 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
     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) {
@@ -723,42 +758,48 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
         * incomplete declaration. Accept this, and if the exsting entry is
         * incomplete, complete it.
         */
-       if (IsTypeArray (Type) && IsTypeArray (EType)) {
+       if (IsTypeArray (T) && IsTypeArray (EType)) {
 
            /* Get the array sizes */
-           long Size  = GetElementCount (Type);
+           long Size  = GetElementCount (T);
            long ESize = GetElementCount (EType);
 
                    if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
-               TypeCmp (Type+DECODE_SIZE+1, EType+DECODE_SIZE+1) < TC_EQUAL) {
+               TypeCmp (T + 1, EType + 1) < TC_EQUAL) {
                /* Types not identical: Conflicting types */
                Error ("Conflicting types for `%s'", Name);
-               return Entry;
+               return Entry;
            } else {
                /* Check if we have a size in the existing definition */
                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 (TypeCmp (EType, Type) < TC_EQUAL) {
+           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) {
                /* 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);
+               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);
+                }
            }
        }
 
@@ -773,7 +814,7 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
        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.