X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Fsymtab.c;h=c54445faec0de0fecbb96804284abb55891ca74a;hb=46209118b1a77d2e57f28026b1e5916c2c074778;hp=7fb88dd1c7cb7a0879db689838b66fb7bc2f2f39;hpb=db656c5e38156b933abe0ec942ffec301c2ed6c2;p=cc65 diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 7fb88dd1c..c54445fae 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -36,6 +36,7 @@ #include /* common */ +#include "cddefs.h" #include "check.h" #include "hashstr.h" #include "symdefs.h" @@ -63,9 +64,9 @@ #define SF_EXPORT 0x0004 /* Export this symbol */ #define SF_IMPORT 0x0008 /* Import this symbol */ #define SF_GLOBAL 0x0010 /* Global symbol */ -#define SF_INITIALIZER 0x0020 /* Exported initializer */ -#define SF_ZP 0x0040 /* Declared as zeropage symbol */ -#define SF_ABS 0x0080 /* Declared as absolute 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 */ @@ -83,35 +84,36 @@ #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 InitVal; /* Initializer value */ + 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 */ }; @@ -166,7 +168,7 @@ static SymEntry* NewSymEntry (const char* Name) S->Pos = CurPos; S->Flags = 0; S->V.Expr = 0; - S->InitVal = 0; + memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio)); memcpy (S->Name, Name, Len+1); /* Insert it into the list of all entries */ @@ -398,7 +400,7 @@ 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 */ { /* Do we have such a symbol? */ @@ -429,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) { @@ -579,15 +584,20 @@ void SymGlobal (const char* Name, int ZP) -void SymInitializer (const char* Name, unsigned InitVal) -/* Mark the given symbol as an initializer. This will also mark the symbol as - * an export. Initializers may never be zero page symbols. +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 InitVal parameter */ - CHECK (InitVal >= EXP_INIT_MIN && InitVal <= EXP_INIT_MAX); + /* 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)) { @@ -613,18 +623,18 @@ void SymInitializer (const char* Name, unsigned InitVal) Error (ERR_SYM_REDECL_MISMATCH); } - /* If the symbol was already declared as an initializer, check if the new - * initializer value is the same as the old one. + /* If the symbol was already declared as a condes, check if the new + * priority value is the same as the old one. */ - if (S->Flags & SF_INITIALIZER) { - if (S->InitVal != InitVal) { + if (S->ConDesPrio[Type] != CD_PRIO_NONE) { + if (S->ConDesPrio[Type] != Prio) { Error (ERR_SYM_REDECL_MISMATCH); } } - S->InitVal = InitVal; + S->ConDesPrio[Type] = Prio; /* Set the symbol data */ - S->Flags |= SF_EXPORT | SF_INITIALIZER | SF_REFERENCED; + S->Flags |= SF_EXPORT | SF_REFERENCED; } @@ -633,7 +643,7 @@ 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; } @@ -1013,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; @@ -1060,10 +1071,31 @@ 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 (); @@ -1080,20 +1112,29 @@ 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; - - /* Add zeropage/abs bits */ - ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS; + /* Get the expression bits */ + ExprMask = GetExprMask (S); - /* Add the initializer bits */ - if (S->Flags & SF_INITIALIZER) { - ExprMask |= S->InitVal; + /* 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 */ 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); @@ -1152,16 +1193,8 @@ 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; - - /* Add zeropage/abs bits */ - ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS; - - /* Add the initializer bits */ - if (S->Flags & SF_INITIALIZER) { - ExprMask |= S->InitVal; - } + /* Get the expression bits */ + ExprMask = GetExprMask (S); /* Write the type */ ObjWrite8 (ExprMask);