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
This commit is contained in:
cuz
2003-12-06 14:16:27 +00:00
parent ad86e4679a
commit eea9accba6
7 changed files with 49 additions and 13 deletions

View File

@@ -38,6 +38,7 @@ OBJS = anonname.o \
repeat.o \ repeat.o \
scanner.o \ scanner.o \
segment.o \ segment.o \
segrange.o \
sizeof.o \ sizeof.o \
spool.o \ spool.o \
struct.o \ struct.o \

View File

@@ -87,6 +87,7 @@ OBJS = anonname.obj \
repeat.obj \ repeat.obj \
scanner.obj \ scanner.obj \
segment.obj \ segment.obj \
segrange.obj \
sizeof.obj \ sizeof.obj \
spool.obj \ spool.obj \
struct.obj \ struct.obj \

View File

@@ -708,7 +708,7 @@ static void DoEnd (void)
static void DoEndProc (void) static void DoEndProc (void)
/* Leave a lexical level */ /* Leave a lexical level */
{ {
if (CurrentScope == RootScope || GetCurrentSymTabType () != ST_PROC) { if (GetCurrentSymTabType () != ST_PROC) {
/* No local scope */ /* No local scope */
ErrorSkip ("No open .PROC"); ErrorSkip ("No open .PROC");
} else { } else {
@@ -721,7 +721,7 @@ static void DoEndProc (void)
static void DoEndScope (void) static void DoEndScope (void)
/* Leave a lexical level */ /* Leave a lexical level */
{ {
if (CurrentScope == RootScope || GetCurrentSymTabType () != ST_SCOPE) { if ( GetCurrentSymTabType () != ST_SCOPE) {
/* No local scope */ /* No local scope */
ErrorSkip ("No open .SCOPE"); ErrorSkip ("No open .SCOPE");
} else { } else {

View File

@@ -91,7 +91,7 @@ static Segment CodeSeg = SEG (&CodeSegDef, 0, &RODataSeg);
static unsigned SegmentCount = 6; static unsigned SegmentCount = 6;
/* List of all segments */ /* List of all segments */
static Segment* SegmentList = &CodeSeg; Segment* SegmentList = &CodeSeg;
static Segment* SegmentLast = &NullSeg; static Segment* SegmentLast = &NullSeg;
/* Currently active segment */ /* Currently active segment */

View File

@@ -78,6 +78,9 @@ extern SegDef BssSegDef;
extern SegDef RODataSegDef; extern SegDef RODataSegDef;
extern SegDef CodeSegDef; extern SegDef CodeSegDef;
/* List of all segments */
extern Segment* SegmentList;
/* Currently active segment */ /* Currently active segment */
extern Segment* ActiveSeg; extern Segment* ActiveSeg;

View File

@@ -50,6 +50,7 @@
#include "objfile.h" #include "objfile.h"
#include "scanner.h" #include "scanner.h"
#include "segment.h" #include "segment.h"
#include "sizeof.h"
#include "spool.h" #include "spool.h"
#include "symtab.h" #include "symtab.h"
@@ -109,6 +110,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
S->Left = 0; S->Left = 0;
S->Right = 0; S->Right = 0;
S->Childs = 0; S->Childs = 0;
S->SegRanges = AUTO_COLLECTION_INITIALIZER;
S->Flags = ST_NONE; S->Flags = ST_NONE;
S->AddrSize = ADDR_SIZE_DEFAULT; S->AddrSize = ADDR_SIZE_DEFAULT;
S->Type = ST_UNDEF; S->Type = ST_UNDEF;
@@ -195,6 +197,16 @@ void SymEnterLevel (const char* ScopeName, unsigned char Type, unsigned char Add
CurrentScope->Flags |= ST_DEFINED; CurrentScope->Flags |= ST_DEFINED;
CurrentScope->AddrSize = AddrSize; CurrentScope->AddrSize = AddrSize;
CurrentScope->Type = Type; 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) void SymLeaveLevel (void)
/* Leave the current lexical level */ /* 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; CurrentScope = CurrentScope->Parent;
} }

View File

@@ -45,6 +45,7 @@
#include "inline.h" #include "inline.h"
/* ca65 */ /* ca65 */
#include "segrange.h"
#include "symentry.h" #include "symentry.h"
@@ -60,12 +61,15 @@
#define ST_DEFINED 0x01 /* Scope has been defined */ #define ST_DEFINED 0x01 /* Scope has been defined */
/* Symbol table types */ /* Symbol table types */
#define ST_GLOBAL 0x00 /* Root level */ enum {
#define ST_PROC 0x01 /* .PROC */ ST_GLOBAL, /* Root level */
#define ST_SCOPE 0x02 /* .SCOPE */ ST_PROC, /* .PROC */
#define ST_STRUCT 0x03 /* .STRUCT/.UNION */ ST_SCOPE, /* .SCOPE */
#define ST_ENUM 0x04 /* .ENUM */ ST_SCOPE_HAS_DATA = ST_SCOPE, /* Last scope that contains data */
#define ST_UNDEF 0xFF ST_STRUCT, /* .STRUCT/.UNION */
ST_ENUM, /* .ENUM */
ST_UNDEF = 0xFF
};
/* A symbol table */ /* A symbol table */
typedef struct SymTable SymTable; typedef struct SymTable SymTable;
@@ -74,6 +78,7 @@ struct SymTable {
SymTable* Right; /* Pointer to greater entry */ SymTable* Right; /* Pointer to greater entry */
SymTable* Parent; /* Link to enclosing scope if any */ SymTable* Parent; /* Link to enclosing scope if any */
SymTable* Childs; /* Pointer to child scopes */ SymTable* Childs; /* Pointer to child scopes */
Collection SegRanges; /* Segment ranges for this scope */
unsigned short Flags; /* Symbol table flags */ unsigned short Flags; /* Symbol table flags */
unsigned char AddrSize; /* Address size */ unsigned char AddrSize; /* Address size */
unsigned char Type; /* Type of the scope */ unsigned char Type; /* Type of the scope */
@@ -168,4 +173,3 @@ void WriteDbgSyms (void);