X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fsymtab.c;h=2c50775d797ffe9e96eaa1993fcc71d5f0141596;hb=c130e597b013e37c94afd6651be1e8859ba7e5ac;hp=11a4252f49a43a3fa7ecbe57f203dd00e7817ee4;hpb=25f5c69efab6e28fe9f12494e83e80140b50556a;p=cc65 diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 11a4252f4..2c50775d7 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -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,23 +161,23 @@ 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 (WARN_UNUSED_PARM, Entry->Name); + Warning ("Parameter `%s' is never used", Entry->Name); } else { - Warning (WARN_UNUSED_ITEM, Entry->Name); + 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) { + Error ("Undefined label: `%s'", Entry->Name); + } else if (!SymIsRef (Entry)) { /* Defined but not used */ - Warning (WARN_UNUSED_ITEM, Entry->Name); + 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); }