X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fsymtab.c;h=6f01b109496cb37d69d1ee37733b6ffbd33b692b;hb=6a988b485952ceb177a212cffdaf1d86446ddfd0;hp=f5ccf6a5134ecf95ac47903725887b9daf69337b;hpb=774b4bb424a03c1fa972a8ebd275ce99ac484ad4;p=cc65 diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index f5ccf6a51..6f01b1094 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-2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -37,21 +37,23 @@ #include #include #include - -#include "../common/hashstr.h" +/* common */ +#include "check.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 "io.h" -#include "mem.h" #include "symentry.h" +#include "typecmp.h" #include "symtab.h" @@ -86,10 +88,8 @@ SymTable EmptySymTab = { static unsigned LexicalLevel = 0; /* For safety checks */ static SymTable* SymTab0 = 0; static SymTable* SymTab = 0; -static SymTable* StructTab0 = 0; -static SymTable* StructTab = 0; -static SymTable* EnumTab0 = 0; -static SymTable* EnumTab = 0; +static SymTable* TagTab0 = 0; +static SymTable* TagTab = 0; static SymTable* LabelTab = 0; @@ -165,9 +165,9 @@ static void CheckSymTable (SymTable* Tab) if (((Flags & SC_AUTO) || (Flags & SC_STATIC)) && (Flags & SC_EXTERN) == 0) { if ((Flags & SC_DEF) && !(Flags & SC_REF)) { 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); } } } @@ -176,10 +176,10 @@ static void CheckSymTable (SymTable* Tab) if (Flags & SC_LABEL) { if ((Flags & SC_DEF) == 0) { /* Undefined label */ - Error (ERR_UNDEFINED_LABEL, Entry->Name); + Error ("Undefined label: `%s'", Entry->Name); } else if ((Flags & SC_REF) == 0) { /* Defined but not used */ - Warning (WARN_UNUSED_ITEM, Entry->Name); + Warning ("`%s' is defined but never used", Entry->Name); } } @@ -207,11 +207,8 @@ void EnterGlobalLevel (void) /* Create and assign the symbol table */ SymTab0 = SymTab = NewSymTable (SYMTAB_SIZE_GLOBAL); - /* Create and assign the struct table */ - StructTab0 = StructTab = NewSymTable (SYMTAB_SIZE_GLOBAL); - - /* Create and assign the enum table */ - EnumTab0 = EnumTab = NewSymTable (SYMTAB_SIZE_GLOBAL); + /* Create and assign the tag table */ + TagTab0 = TagTab = NewSymTable (SYMTAB_SIZE_GLOBAL); } @@ -227,15 +224,13 @@ void LeaveGlobalLevel (void) /* Dump the tables if requested */ if (Debug) { - PrintSymTable (SymTab0, stdout, "Global symbol table"); - PrintSymTable (StructTab0, stdout, "Global struct table"); - PrintSymTable (EnumTab0, stdout, "Global enum table"); + PrintSymTable (SymTab0, stdout, "Global symbol table"); + PrintSymTable (TagTab0, stdout, "Global tag table"); } /* Don't delete the symbol and struct tables! */ - SymTab0 = SymTab = 0; - StructTab0 = StructTab = 0; - EnumTab0 = EnumTab = 0; + SymTab = 0; + TagTab = 0; } @@ -253,15 +248,10 @@ void EnterFunctionLevel (void) S->PrevTab = SymTab; SymTab = S; - /* Get a new struct table and make it current */ + /* Get a new tag table and make it current */ S = NewSymTable (SYMTAB_SIZE_FUNCTION); - S->PrevTab = StructTab; - StructTab = S; - - /* Get a new enum table and make it current */ - S = NewSymTable (SYMTAB_SIZE_FUNCTION); - S->PrevTab = EnumTab; - EnumTab = S; + S->PrevTab = TagTab; + TagTab = S; /* Create and assign a new label table */ LabelTab = NewSymTable (SYMTAB_SIZE_LABEL); @@ -276,14 +266,12 @@ void RememberFunctionLevel (struct FuncDesc* F) --LexicalLevel; /* Remember the tables */ - F->SymTab = SymTab; - F->StructTab = StructTab; - F->EnumTab = EnumTab; + F->SymTab = SymTab; + F->TagTab = TagTab; /* Don't delete the tables */ - SymTab = SymTab->PrevTab; - StructTab = StructTab->PrevTab; - EnumTab = EnumTab->PrevTab; + SymTab = SymTab->PrevTab; + TagTab = TagTab->PrevTab; } @@ -298,11 +286,8 @@ void ReenterFunctionLevel (struct FuncDesc* F) F->SymTab->PrevTab = SymTab; SymTab = F->SymTab; - F->StructTab->PrevTab = StructTab; - StructTab = F->StructTab; - - F->EnumTab->PrevTab = EnumTab; - EnumTab = F->EnumTab; + F->TagTab->PrevTab = TagTab; + TagTab = F->TagTab; /* Create and assign a new label table */ LabelTab = NewSymTable (SYMTAB_SIZE_LABEL); @@ -326,9 +311,8 @@ void LeaveFunctionLevel (void) } /* Don't delete the tables */ - SymTab = SymTab->PrevTab; - StructTab = StructTab->PrevTab; - EnumTab = EnumTab->PrevTab; + SymTab = SymTab->PrevTab; + TagTab = TagTab->PrevTab; LabelTab = 0; } @@ -347,15 +331,10 @@ void EnterBlockLevel (void) S->PrevTab = SymTab; SymTab = S; - /* Get a new struct table and make it current */ - S = NewSymTable (SYMTAB_SIZE_BLOCK); - S->PrevTab = StructTab; - StructTab = S; - - /* Get a new enum table and make it current */ + /* Get a new tag table and make it current */ S = NewSymTable (SYMTAB_SIZE_BLOCK); - S->PrevTab = EnumTab; - EnumTab = S; + S->PrevTab = TagTab; + TagTab = S; } @@ -370,9 +349,8 @@ void LeaveBlockLevel (void) CheckSymTable (SymTab); /* Don't delete the tables */ - SymTab = SymTab->PrevTab; - StructTab = StructTab->PrevTab; - EnumTab = EnumTab->PrevTab; + SymTab = SymTab->PrevTab; + TagTab = TagTab->PrevTab; } @@ -463,18 +441,26 @@ SymEntry* FindSym (const char* Name) -SymEntry* FindStructSym (const char* Name) -/* Find the symbol with the given name in the struct table */ +SymEntry* FindGlobalSym (const char* Name) +/* Find the symbol with the given name in the global symbol table only */ { - return FindSymInTree (StructTab, Name); + return FindSymInTable (SymTab0, Name, HashStr (Name)); } -SymEntry* FindEnumSym (const char* Name) -/* Find the symbol with the given name in the enum table */ +SymEntry* FindLocalSym (const char* Name) +/* Find the symbol with the given name in the current symbol table only */ { - return FindSymInTree (EnumTab, Name); + return FindSymInTable (SymTab, Name, HashStr (Name)); +} + + + +SymEntry* FindTagSym (const char* Name) +/* Find the symbol with the given name in the tag table */ +{ + return FindSymInTree (TagTab, Name); } @@ -490,7 +476,7 @@ SymEntry* FindStructField (const type* Type, const char* Name) } /* Non-structs do not have any struct fields... */ - if (IsStruct (Type)) { + if (IsClassStruct (Type)) { const SymTable* Tab; @@ -552,16 +538,16 @@ SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab) /* Add a struct/union entry and return it */ { /* Do we have an entry with this name already? */ - SymEntry* Entry = FindSymInTable (StructTab, Name, HashStr (Name)); + SymEntry* Entry = FindSymInTable (TagTab, Name, HashStr (Name)); if (Entry) { /* We do have an entry. This may be a forward, so check it. */ - if (Entry->Flags != SC_STRUCT) { + 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) { @@ -580,7 +566,7 @@ SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab) Entry->V.S.Size = Size; /* Add it to the current table */ - AddSymEntry (StructTab, Entry); + AddSymEntry (TagTab, Entry); } /* Return the entry */ @@ -589,28 +575,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); @@ -630,7 +616,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) if ((Entry->Flags & SC_DEF) != 0 && (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; @@ -640,7 +626,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); @@ -653,25 +639,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* Type, 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 { @@ -693,11 +669,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 = 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)); @@ -707,7 +686,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; } @@ -718,16 +697,17 @@ 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 (Type) && 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); + TypeCmp (Type+DECODE_SIZE+1, EType+DECODE_SIZE+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) { @@ -738,16 +718,21 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags) } else { /* New type must be identical */ - if (!EqualTypes (EType, Type) != 0) { - Error (ERR_MULTIPLE_DEFINITION, Name); + if (TypeCmp (EType, Type) < 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. */ - if (IsFunc (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); } } @@ -762,6 +747,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); } @@ -786,128 +779,18 @@ SymTable* GetSymTab (void) -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; - - - /* 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 ((F1->Flags & ~FD_IMPLICIT) != (F2->Flags & ~FD_IMPLICIT)) { - /* Flags differ */ - return 0; - } - - /* Compare the parameter lists */ - if (EqualSymTables (F1->SymTab, F2->SymTab) == 0 || - EqualSymTables (F1->StructTab, F2->StructTab) == 0 || - EqualSymTables (F1->EnumTab, F2->EnumTab) == 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); } @@ -922,7 +805,7 @@ void MakeZPSym (const char* Name) if (Entry) { Entry->Flags |= SC_ZEROPAGE; } else { - Error (ERR_UNDEFINED_SYMBOL, Name); + Error ("Undefined symbol: `%s'", Name); } } @@ -968,8 +851,6 @@ void EmitExternals (void) { SymEntry* Entry; - AddEmptyLine (); - Entry = SymTab->SymHead; while (Entry) { unsigned Flags = Entry->Flags;