X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Fsymtab.c;h=c54445faec0de0fecbb96804284abb55891ca74a;hb=46209118b1a77d2e57f28026b1e5916c2c074778;hp=027f715ddf224f7b811d34bd944719d0dcf3a6dc;hpb=5ee8618510eacaca1f779612103bf709f59e9450;p=cc65 diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 027f715dd..c54445fae 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -36,6 +36,7 @@ #include /* common */ +#include "cddefs.h" #include "check.h" #include "hashstr.h" #include "symdefs.h" @@ -46,6 +47,7 @@ #include "error.h" #include "expr.h" #include "objfile.h" +#include "scanner.h" #include "symtab.h" @@ -64,6 +66,7 @@ #define SF_GLOBAL 0x0010 /* Global symbol */ #define SF_ZP 0x0020 /* Declared as zeropage symbol */ #define SF_ABS 0x0040 /* Declared as absolute symbol */ +#define SF_LABEL 0x0080 /* Used as a label */ #define SF_INDEXED 0x0800 /* Index is valid */ #define SF_CONST 0x1000 /* The symbol has a constant value */ #define SF_MULTDEF 0x2000 /* Multiply defined symbol */ @@ -80,41 +83,47 @@ #define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT) #define SF_DBGINFOVAL (SF_DEFINED) - - /* Structure of a symbol table entry */ -struct SymEntry_ { +struct SymEntry { SymEntry* Left; /* Lexically smaller entry */ - SymEntry* Right; /* Lexically larger entry */ - SymEntry* List; /* List of all entries */ + SymEntry* Right; /* Lexically larger entry */ + SymEntry* List; /* List of all entries */ SymEntry* Locals; /* Root of subtree for local symbols */ - struct SymTable_* SymTab; /* Table this symbol is in, 0 for locals */ + struct SymTable* SymTab; /* Table this symbol is in, 0 for locals */ FilePos Pos; /* File position for this symbol */ unsigned Flags; /* Symbol flags */ unsigned Index; /* Index of import/export entries */ union { - struct ExprNode_* Expr; /* Expression if CONST not set */ + struct ExprNode* Expr; /* Expression if CONST not set */ long Val; /* Value (if CONST set) */ - SymEntry* Sym; /* Symbol (if trampoline entry) */ + SymEntry* Sym; /* Symbol (if trampoline entry) */ } V; + unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */ + /* ...actually value+1 (used as flag) */ char Name [1]; /* Dynamic allocation */ }; /* Definitions for the hash table */ -#define MAIN_HASHTAB_SIZE 213 -#define SUB_HASHTAB_SIZE 53 -typedef struct SymTable_ SymTable; -struct SymTable_ { - unsigned TableSlots; /* Number of hash table slots */ - unsigned TableEntries; /* Number of entries in the table */ +#define MAIN_HASHTAB_SIZE 213 +#define SUB_HASHTAB_SIZE 53 +typedef struct SymTable SymTable; +struct SymTable { + unsigned TableSlots; /* Number of hash table slots */ + unsigned TableEntries; /* Number of entries in the table */ SymTable* BackLink; /* Link to enclosing scope if any */ - SymEntry* Table [1]; /* Dynamic allocation */ + SymEntry* Table [1]; /* Dynamic allocation */ }; +/* Arguments for SymFind */ +#define SF_FIND_EXISTING 0 +#define SF_ALLOC_NEW 1 + + + /* Symbol table variables */ static SymEntry* SymList = 0; /* List of all symbol table entries */ static SymEntry* SymLast = 0; /* Pointer to last defined symbol */ @@ -152,13 +161,14 @@ static SymEntry* NewSymEntry (const char* Name) S = xmalloc (sizeof (SymEntry) + Len); /* Initialize the entry */ - S->Left = 0; - S->Right = 0; - S->Locals = 0; - S->SymTab = 0; - S->Flags = 0; - S->V.Expr = 0; - S->Pos = CurPos; + S->Left = 0; + S->Right = 0; + S->Locals = 0; + S->SymTab = 0; + S->Pos = CurPos; + S->Flags = 0; + S->V.Expr = 0; + memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio)); memcpy (S->Name, Name, Len+1); /* Insert it into the list of all entries */ @@ -353,10 +363,8 @@ static SymEntry* SymFindAny (SymTable* Tab, const char* Name) static SymEntry* SymRefInternal (SymTable* Table, const char* Name) /* Search for the symbol in the given table and return it */ { - SymEntry* S; - /* Try to find the symbol, create a new one if the symbol does not exist */ - S = SymFind (Table, Name, 1); + SymEntry* S = SymFind (Table, Name, SF_ALLOC_NEW); /* Mark the symbol as referenced */ S->Flags |= SF_REFERENCED; @@ -392,16 +400,14 @@ void SymLeaveLevel (void) -void SymDef (const char* Name, ExprNode* Expr, int ZP) +void SymDef (const char* Name, ExprNode* Expr, int ZP, int Label) /* Define a new symbol */ { - SymEntry* S; - /* Do we have such a symbol? */ - S = SymFind (SymTab, Name, 1); + SymEntry* S = SymFind (SymTab, Name, SF_ALLOC_NEW); if (S->Flags & SF_IMPORT) { /* Defined symbol is marked as imported external symbol */ - Error (ERR_SYM_ALREADY_IMPORT); + Error (ERR_SYM_ALREADY_IMPORT, Name); return; } if (S->Flags & SF_DEFINED) { @@ -425,6 +431,9 @@ void SymDef (const char* Name, ExprNode* Expr, int ZP) if (ZP) { S->Flags |= SF_ZP; } + if (Label) { + S->Flags |= SF_LABEL; + } /* If the symbol is a ZP symbol, check if the value is in correct range */ if (S->Flags & SF_ZP) { @@ -472,7 +481,7 @@ void SymImport (const char* Name, int ZP) } /* Do we have such a symbol? */ - S = SymFind (SymTab, Name, 1); + S = SymFind (SymTab, Name, SF_ALLOC_NEW); if (S->Flags & SF_DEFINED) { Error (ERR_SYM_ALREADY_DEFINED, Name); S->Flags |= SF_MULTDEF; @@ -480,7 +489,7 @@ void SymImport (const char* Name, int ZP) } if (S->Flags & SF_EXPORT) { /* The symbol is already marked as exported symbol */ - Error (ERR_SYM_ALREADY_EXPORT); + Error (ERR_SYM_ALREADY_EXPORT, Name); return; } @@ -515,10 +524,10 @@ void SymExport (const char* Name, int ZP) } /* Do we have such a symbol? */ - S = SymFind (SymTab, Name, 1); + S = SymFind (SymTab, Name, SF_ALLOC_NEW); if (S->Flags & SF_IMPORT) { /* The symbol is already marked as imported external symbol */ - Error (ERR_SYM_ALREADY_IMPORT); + Error (ERR_SYM_ALREADY_IMPORT, Name); return; } @@ -555,7 +564,7 @@ void SymGlobal (const char* Name, int ZP) } /* Search for this symbol, create a new entry if needed */ - S = SymFind (SymTab, Name, 1); + S = SymFind (SymTab, Name, SF_ALLOC_NEW); /* If the symbol is already marked as import or export, check the * size of the definition, then bail out. */ @@ -575,11 +584,66 @@ void SymGlobal (const char* Name, int ZP) +void SymConDes (const char* Name, unsigned Type, unsigned Prio) +/* Mark the given symbol as a module constructor/destructor. This will also + * mark the symbol as an export. Initializers may never be zero page symbols. + */ +{ + SymEntry* S; + + /* Check the parameters */ +#if (CD_TYPE_MIN != 0) + CHECK (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX); +#else + CHECK (Type <= CD_TYPE_MAX); +#endif + CHECK (Prio >= CD_PRIO_MIN && Prio <= CD_PRIO_MAX); + + /* Don't accept local symbols */ + if (IsLocal (Name)) { + Error (ERR_ILLEGAL_LOCAL_USE); + return; + } + + /* Do we have such a symbol? */ + S = SymFind (SymTab, Name, SF_ALLOC_NEW); + if (S->Flags & SF_IMPORT) { + /* The symbol is already marked as imported external symbol */ + Error (ERR_SYM_ALREADY_IMPORT, Name); + return; + } + + /* If the symbol is marked as global, silently remove the global flag */ + if (S->Flags & SF_GLOBAL) { + S->Flags &= ~SF_GLOBAL; + } + + /* Check if the symbol was not already defined as ZP symbol */ + if ((S->Flags & SF_ZP) != 0) { + Error (ERR_SYM_REDECL_MISMATCH); + } + + /* If the symbol was already declared as a condes, check if the new + * priority value is the same as the old one. + */ + if (S->ConDesPrio[Type] != CD_PRIO_NONE) { + if (S->ConDesPrio[Type] != Prio) { + Error (ERR_SYM_REDECL_MISMATCH); + } + } + S->ConDesPrio[Type] = Prio; + + /* Set the symbol data */ + S->Flags |= SF_EXPORT | SF_REFERENCED; +} + + + int SymIsDef (const char* Name) /* Return true if the given symbol is already defined */ { SymEntry* S = SymFindAny (SymTab, Name); - return S != 0 && (S->Flags & (SF_DEFINED | SF_IMPORT)) != 0; + return S != 0 && (S->Flags & SF_DEFINED) != 0; } @@ -851,7 +915,7 @@ static void SymCheckUndefined (SymEntry* S) if (S->Flags & SF_EXPORT) { if (Sym->Flags & SF_IMPORT) { /* The symbol is already marked as imported external symbol */ - PError (&S->Pos, ERR_SYM_ALREADY_IMPORT); + PError (&S->Pos, ERR_SYM_ALREADY_IMPORT, S->Name); } Sym->Flags |= S->Flags & (SF_EXPORT | SF_ZP); } @@ -959,13 +1023,14 @@ void SymDump (FILE* F) while (S) { /* Ignore trampoline symbols */ if ((S->Flags & SF_TRAMPOLINE) != 0) { - printf ("%-24s %s %s %s %s %s\n", - S->Name, - (S->Flags & SF_DEFINED)? "DEF" : "---", - (S->Flags & SF_REFERENCED)? "REF" : "---", - (S->Flags & SF_IMPORT)? "IMP" : "---", - (S->Flags & SF_EXPORT)? "EXP" : "---", - (S->Flags & SF_ZP)? "ZP" : "--"); + fprintf (F, + "%-24s %s %s %s %s %s\n", + S->Name, + (S->Flags & SF_DEFINED)? "DEF" : "---", + (S->Flags & SF_REFERENCED)? "REF" : "---", + (S->Flags & SF_IMPORT)? "IMP" : "---", + (S->Flags & SF_EXPORT)? "EXP" : "---", + (S->Flags & SF_ZP)? "ZP" : "--"); } /* Next symbol */ S = S->List; @@ -983,7 +1048,7 @@ void WriteImports (void) ObjStartImports (); /* Write the import count to the list */ - ObjWrite16 (ImportCount); + ObjWriteVar (ImportCount); /* Walk throught list and write all imports to the file */ S = SymList; @@ -1006,16 +1071,37 @@ void WriteImports (void) +static unsigned char GetExprMask (SymEntry* S) +/* Return the expression bits for the given symbol table entry */ +{ + unsigned char ExprMask; + + /* Check if the symbol is const */ + ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR; + + /* Add zeropage/abs bits */ + ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS; + + /* Add the label/equate bits */ + ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE; + + /* Return the mask */ + return ExprMask; +} + + + void WriteExports (void) /* Write the exports list to the object file */ { SymEntry* S; + unsigned Type; /* Tell the object file module that we're about to start the exports */ ObjStartExports (); /* Write the export count to the list */ - ObjWrite16 (ExportCount); + ObjWriteVar (ExportCount); /* Walk throught list and write all exports to the file */ S = SymList; @@ -1026,23 +1112,42 @@ void WriteExports (void) /* Finalize an associated expression if we have one */ SymFinalize (S); - /* Check if the symbol is const */ - ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR; + /* Get the expression bits */ + ExprMask = GetExprMask (S); + + /* Count the number of ConDes types */ + for (Type = 0; Type < CD_TYPE_COUNT; ++Type) { + if (S->ConDesPrio[Type] != CD_PRIO_NONE) { + INC_EXP_CONDES_COUNT (ExprMask); + } + } /* Write the type */ - if (S->Flags & SF_ZP) { - ObjWrite8 (EXP_ZP | ExprMask); - } else { - ObjWrite8 (EXP_ABS | ExprMask); + ObjWrite8 (ExprMask); + + /* Write any ConDes declarations */ + if (GET_EXP_CONDES_COUNT (ExprMask) > 0) { + for (Type = 0; Type < CD_TYPE_COUNT; ++Type) { + unsigned char Prio = S->ConDesPrio[Type]; + if (Prio != CD_PRIO_NONE) { + ObjWrite8 (CD_BUILD (Type, Prio)); + } + } } + + /* Write the name */ ObjWriteStr (S->Name); - if (ExprMask == EXP_CONST) { + + /* Write the value */ + if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) { /* Constant value */ ObjWrite32 (S->V.Val); } else { /* Expression involved */ WriteExpr (S->V.Expr); } + + /* Write the source file position */ ObjWritePos (&S->Pos); } S = S->List; @@ -1076,13 +1181,8 @@ void WriteDbgSyms (void) S = S->List; } - /* Safety check */ - if (Count > 0xFFFF) { - Fatal (FAT_TOO_MANY_SYMBOLS); - } - /* Write the symbol count to the list */ - ObjWrite16 (Count); + ObjWriteVar (Count); /* Walk through list and write all symbols to the file */ S = SymList; @@ -1093,23 +1193,25 @@ void WriteDbgSyms (void) /* Finalize an associated expression if we have one */ SymFinalize (S); - /* Check if the symbol is const */ - ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR; + /* Get the expression bits */ + ExprMask = GetExprMask (S); /* Write the type */ - if (S->Flags & SF_ZP) { - ObjWrite8 (EXP_ZP | ExprMask); - } else { - ObjWrite8 (EXP_ABS | ExprMask); - } + ObjWrite8 (ExprMask); + + /* Write the name */ ObjWriteStr (S->Name); - if (ExprMask == EXP_CONST) { + + /* Write the value */ + if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) { /* Constant value */ ObjWrite32 (S->V.Val); } else { /* Expression involved */ WriteExpr (S->V.Expr); } + + /* Write the source file position */ ObjWritePos (&S->Pos); } S = S->List; @@ -1118,7 +1220,7 @@ void WriteDbgSyms (void) } else { /* No debug symbols */ - ObjWrite16 (0); + ObjWriteVar (0); }