From 607aa871e6b4a820c0becc41df7e44fca2b91c7d Mon Sep 17 00:00:00 2001 From: uz Date: Fri, 19 Aug 2011 15:24:11 +0000 Subject: [PATCH] Last fix was wrong. The problem wasn't in the struct code but in SymLeaveLevel calling CloseSpans, which does not only close spans but might also add some, in which case the scope became another size. git-svn-id: svn://svn.cc65.org/cc65/trunk@5232 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/make/gcc.mak | 2 +- src/ca65/struct.c | 11 +++++++++-- src/ca65/symtab.c | 8 +++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ca65/make/gcc.mak b/src/ca65/make/gcc.mak index 176e246e2..46d432bbd 100644 --- a/src/ca65/make/gcc.mak +++ b/src/ca65/make/gcc.mak @@ -15,7 +15,7 @@ CA65_INC = \"/usr/lib/cc65/asminc/\" # CC = gcc -CFLAGS = -g -Wall -W -std=c89 +CFLAGS = -g -O2 -Wall -W -std=c89 override CFLAGS += -I$(COMMON) override CFLAGS += -DCA65_INC=$(CA65_INC) EBIND = emxbind diff --git a/src/ca65/struct.c b/src/ca65/struct.c index a716c861a..07068ef94 100644 --- a/src/ca65/struct.c +++ b/src/ca65/struct.c @@ -244,10 +244,17 @@ static long DoStructInternal (long Offs, unsigned Type) ConsumeSep (); } - /* If this is not a anon struct, leave the struct scope level. This will - * also record the size of the scope. + /* If this is not a anon struct, enter a special symbol named ".size" + * into the symbol table of the struct that holds the size of the + * struct. Since the symbol starts with a dot, it cannot be accessed + * by user code. + * Leave the struct scope level. */ if (!Anon) { + /* Add a symbol */ + SymEntry* SizeSym = GetSizeOfScope (CurrentScope); + SymDef (SizeSym, GenLiteralExpr (Size), ADDR_SIZE_DEFAULT, SF_NONE); + /* Close the struct scope */ SymLeaveLevel (); } diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 653506691..bc64b0364 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -244,10 +244,12 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type, void SymLeaveLevel (void) /* Leave the current lexical level */ { - /* Close the spans. We don't care about the scope type here, since types - * without spans will just have an empty list. + /* If this is a scope that allows to emit data into segments, close the + * open the spans. */ - CloseSpans (&CurrentScope->Spans); + if (CurrentScope->Type <= SCOPE_HAS_DATA) { + CloseSpans (&CurrentScope->Spans); + } /* If we have spans, 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