X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fsymtab.c;h=5a7c740d3316169b4cb2cc491e6d80f0ae30b180;hb=9b7c16ec4cbb5282642c377272224e3fc825f860;hp=988190cd6a50a462790cde0a3c29433774e63bcb;hpb=ede471904c740b4f58112f7101beccfbc41571fe;p=cc65 diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 988190cd6..5a7c740d3 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* 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 */ @@ -40,6 +40,7 @@ /* common */ #include "check.h" +#include "debugflag.h" #include "hashstr.h" #include "xmalloc.h" @@ -52,6 +53,7 @@ #include "error.h" #include "funcdesc.h" #include "global.h" +#include "stackptr.h" #include "symentry.h" #include "typecmp.h" #include "symtab.h" @@ -81,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; @@ -157,17 +156,22 @@ 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 (SymIsDef (Entry) && !SymIsRef (Entry)) { + if (SymIsDef (Entry) && !SymIsRef (Entry) && + !SymHasAttr (Entry, atUnused)) { 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); + } } } } @@ -179,7 +183,9 @@ static void CheckSymTable (SymTable* Tab) Error ("Undefined label: `%s'", Entry->Name); } else if (!SymIsRef (Entry)) { /* Defined but not used */ - Warning ("`%s' is defined but never used", Entry->Name); + if (IS_Get (&WarnUnusedLabel)) { + Warning ("`%s' is defined but never used", Entry->Name); + } } } @@ -198,6 +204,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 */ { @@ -465,32 +479,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)); } } @@ -522,7 +531,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]; @@ -575,11 +584,46 @@ SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab) -SymEntry* AddConstSym (const char* Name, const type* Type, unsigned Flags, long Val) -/* Add an constant 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) { + + /* 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); @@ -593,13 +637,13 @@ 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; /* Add the entry to the symbol table */ - AddSymEntry (SymTab, Entry); + AddSymEntry (Tab, Entry); /* Return the entry */ return Entry; @@ -628,6 +672,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Set a new label number */ 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); @@ -639,7 +686,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? */ @@ -655,14 +702,18 @@ 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 = oursp; /* ### Cleaner! */ + 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 { @@ -680,11 +731,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; @@ -693,7 +744,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) { @@ -708,42 +759,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 */ - unsigned Size = Decode (Type + 1); - unsigned ESize = Decode (EType + 1); + long Size = GetElementCount (T); + long ESize = GetElementCount (EType); - if ((Size != 0 && ESize != 0 && Size != ESize) || - TypeCmp (Type+DECODE_SIZE+1, EType+DECODE_SIZE+1) < TC_EQUAL) { + 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; + 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 (TypeCmp (EType, Type) < TC_EQUAL) { + if (TypeCmp (EType, T) < TC_EQUAL) { Error ("Conflicting types for `%s'", Name); - return Entry; + 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); + /* 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); + } } } @@ -752,11 +809,13 @@ SymEntry* AddGlobalSym (const char* Name, const 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. @@ -766,6 +825,12 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags) 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); }