]> git.sur5r.net Git - cc65/commitdiff
Make .sizeof work with code scopes. First support for segment ranges.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 6 Dec 2003 14:16:27 +0000 (14:16 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 6 Dec 2003 14:16:27 +0000 (14:16 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2718 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/make/gcc.mak
src/ca65/make/watcom.mak
src/ca65/pseudo.c
src/ca65/segment.c
src/ca65/segment.h
src/ca65/symtab.c
src/ca65/symtab.h

index 87c6b169200634d8777dd24c816913c88a268fb2..950d725dcaa5f502d9e196d3903d999e24199874 100644 (file)
@@ -38,6 +38,7 @@ OBJS =  anonname.o      \
        repeat.o        \
         scanner.o      \
         segment.o       \
+        segrange.o      \
         sizeof.o        \
         spool.o         \
         struct.o        \
index d8b294a8de6b963cb3e58a2c462e77d524baf3f6..fa7d9ee652fe57ac5326309fd16fa421397e5b55 100644 (file)
@@ -87,6 +87,7 @@ OBJS =        anonname.obj    \
        repeat.obj      \
        scanner.obj     \
         segment.obj     \
+        segrange.obj    \
         sizeof.obj      \
         spool.obj       \
         struct.obj      \
index b6460fe7294086eb06133a6e77454dbcb7a23a7d..018232717beb2d8c54d141556fe58623fb63750f 100644 (file)
@@ -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;
 
index c0e64b5018b66c8b117f13d3d8f8f3e27edbf102..27066844f529e0d37b100eb2d2a105d393f38f0a 100644 (file)
@@ -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 */
index 57da0313001e339a0ed76ed1d3d90a1619ab05d1..fb0a02dd4269ad15210f19e140cb838b34271945 100644 (file)
@@ -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;
 
index 68e2237c2f8cea7cda633969bc8696828feb54e1..52a6f9f20204ed6dcb2ef23494502f05f3b5e295 100644 (file)
@@ -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;
 }
 
index 22c0e778b71427c311ec397c95759be8c883aa9b..aaac2eeb8e04eb47102db314d852e2b9ea41fe75 100644 (file)
@@ -45,6 +45,7 @@
 #include "inline.h"
 
 /* ca65 */
+#include "segrange.h"
 #include "symentry.h"
 
 
 #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);
 
 
 
-