From: cuz Date: Sat, 6 Dec 2003 14:16:27 +0000 (+0000) Subject: Make .sizeof work with code scopes. First support for segment ranges. X-Git-Tag: V2.12.0~1085 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=eea9accba62e6e7b4d0f579585de21d055b498f9;p=cc65 Make .sizeof work with code scopes. First support for segment ranges. git-svn-id: svn://svn.cc65.org/cc65/trunk@2718 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/ca65/make/gcc.mak b/src/ca65/make/gcc.mak index 87c6b1692..950d725dc 100644 --- a/src/ca65/make/gcc.mak +++ b/src/ca65/make/gcc.mak @@ -38,6 +38,7 @@ OBJS = anonname.o \ repeat.o \ scanner.o \ segment.o \ + segrange.o \ sizeof.o \ spool.o \ struct.o \ diff --git a/src/ca65/make/watcom.mak b/src/ca65/make/watcom.mak index d8b294a8d..fa7d9ee65 100644 --- a/src/ca65/make/watcom.mak +++ b/src/ca65/make/watcom.mak @@ -87,6 +87,7 @@ OBJS = anonname.obj \ repeat.obj \ scanner.obj \ segment.obj \ + segrange.obj \ sizeof.obj \ spool.obj \ struct.obj \ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index b6460fe72..018232717 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -708,7 +708,7 @@ static void DoEnd (void) static void DoEndProc (void) /* Leave a lexical level */ { - if (CurrentScope == RootScope || GetCurrentSymTabType () != ST_PROC) { + if (GetCurrentSymTabType () != ST_PROC) { /* No local scope */ ErrorSkip ("No open .PROC"); } else { @@ -721,7 +721,7 @@ static void DoEndProc (void) static void DoEndScope (void) /* Leave a lexical level */ { - if (CurrentScope == RootScope || GetCurrentSymTabType () != ST_SCOPE) { + if ( GetCurrentSymTabType () != ST_SCOPE) { /* No local scope */ ErrorSkip ("No open .SCOPE"); } else { @@ -1508,7 +1508,7 @@ static void DoSunPlus (void) static void DoTag (void) /* Allocate space for a struct */ -{ +{ SymEntry* SizeSym; long Size; diff --git a/src/ca65/segment.c b/src/ca65/segment.c index c0e64b501..27066844f 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -91,7 +91,7 @@ static Segment CodeSeg = SEG (&CodeSegDef, 0, &RODataSeg); static unsigned SegmentCount = 6; /* List of all segments */ -static Segment* SegmentList = &CodeSeg; +Segment* SegmentList = &CodeSeg; static Segment* SegmentLast = &NullSeg; /* Currently active segment */ diff --git a/src/ca65/segment.h b/src/ca65/segment.h index 57da03130..fb0a02dd4 100644 --- a/src/ca65/segment.h +++ b/src/ca65/segment.h @@ -78,6 +78,9 @@ extern SegDef BssSegDef; extern SegDef RODataSegDef; extern SegDef CodeSegDef; +/* List of all segments */ +extern Segment* SegmentList; + /* Currently active segment */ extern Segment* ActiveSeg; diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 68e2237c2..52a6f9f20 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -50,6 +50,7 @@ #include "objfile.h" #include "scanner.h" #include "segment.h" +#include "sizeof.h" #include "spool.h" #include "symtab.h" @@ -109,6 +110,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name) S->Left = 0; S->Right = 0; S->Childs = 0; + S->SegRanges = AUTO_COLLECTION_INITIALIZER; S->Flags = ST_NONE; S->AddrSize = ADDR_SIZE_DEFAULT; S->Type = ST_UNDEF; @@ -195,6 +197,16 @@ void SymEnterLevel (const char* ScopeName, unsigned char Type, unsigned char Add CurrentScope->Flags |= ST_DEFINED; CurrentScope->AddrSize = AddrSize; CurrentScope->Type = Type; + + /* If this is a scope that allows to emit data into segments, add segment + * ranges for all currently existing segments. Doing this for just a few + * scope types is not really necessary but an optimization, because it + * does not allocate memory for useless data (unhandled types here don't + * occupy space in any segment). + */ + if (CurrentScope->Type <= ST_SCOPE_HAS_DATA) { + AddSegRanges (&CurrentScope->SegRanges); + } } @@ -202,6 +214,21 @@ void SymEnterLevel (const char* ScopeName, unsigned char Type, unsigned char Add void SymLeaveLevel (void) /* Leave the current lexical level */ { + /* Close the segment ranges. We don't care about the scope type here, + * since types without segment ranges will just have an empty list. + */ + CloseSegRanges (&CurrentScope->SegRanges); + + /* If we have segment ranges, the first one is the segment that was + * active, when the scope was opened. Set the size of the scope to the + * number of data bytes emitted into this segment. + */ + if (CollCount (&CurrentScope->SegRanges) > 0) { + const SegRange* R = CollAtUnchecked (&CurrentScope->SegRanges, 0); + DefSizeOfScope (CurrentScope, GetSegRangeSize (R)); + } + + /* Leave the scope */ CurrentScope = CurrentScope->Parent; } diff --git a/src/ca65/symtab.h b/src/ca65/symtab.h index 22c0e778b..aaac2eeb8 100644 --- a/src/ca65/symtab.h +++ b/src/ca65/symtab.h @@ -45,6 +45,7 @@ #include "inline.h" /* ca65 */ +#include "segrange.h" #include "symentry.h" @@ -60,12 +61,15 @@ #define ST_DEFINED 0x01 /* Scope has been defined */ /* Symbol table types */ -#define ST_GLOBAL 0x00 /* Root level */ -#define ST_PROC 0x01 /* .PROC */ -#define ST_SCOPE 0x02 /* .SCOPE */ -#define ST_STRUCT 0x03 /* .STRUCT/.UNION */ -#define ST_ENUM 0x04 /* .ENUM */ -#define ST_UNDEF 0xFF +enum { + ST_GLOBAL, /* Root level */ + ST_PROC, /* .PROC */ + ST_SCOPE, /* .SCOPE */ + ST_SCOPE_HAS_DATA = ST_SCOPE, /* Last scope that contains data */ + ST_STRUCT, /* .STRUCT/.UNION */ + ST_ENUM, /* .ENUM */ + ST_UNDEF = 0xFF +}; /* A symbol table */ typedef struct SymTable SymTable; @@ -74,12 +78,13 @@ struct SymTable { SymTable* Right; /* Pointer to greater entry */ SymTable* Parent; /* Link to enclosing scope if any */ SymTable* Childs; /* Pointer to child scopes */ + Collection SegRanges; /* Segment ranges for this scope */ unsigned short Flags; /* Symbol table flags */ - unsigned char AddrSize; /* Address size */ + unsigned char AddrSize; /* Address size */ unsigned char Type; /* Type of the scope */ unsigned Level; /* Lexical level */ unsigned TableSlots; /* Number of hash table slots */ - unsigned TableEntries; /* Number of entries in the table */ + unsigned TableEntries; /* Number of entries in the table */ unsigned Name; /* Name of the scope */ SymEntry* Table[1]; /* Dynamic allocation */ }; @@ -168,4 +173,3 @@ void WriteDbgSyms (void); -