mirror of
https://github.com/cc65/cc65.git
synced 2025-02-03 22:32:24 +00:00
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:
parent
ad86e4679a
commit
eea9accba6
@ -38,6 +38,7 @@ OBJS = anonname.o \
|
||||
repeat.o \
|
||||
scanner.o \
|
||||
segment.o \
|
||||
segrange.o \
|
||||
sizeof.o \
|
||||
spool.o \
|
||||
struct.o \
|
||||
|
@ -87,6 +87,7 @@ OBJS = anonname.obj \
|
||||
repeat.obj \
|
||||
scanner.obj \
|
||||
segment.obj \
|
||||
segrange.obj \
|
||||
sizeof.obj \
|
||||
spool.obj \
|
||||
struct.obj \
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user