From 14d0577ef0fa948f89a9d5b35974c6de82186ef1 Mon Sep 17 00:00:00 2001 From: cuz Date: Wed, 3 Dec 2003 09:18:31 +0000 Subject: [PATCH] More work on .sizeof, fixed problems with cheap locals git-svn-id: svn://svn.cc65.org/cc65/trunk@2704 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/expr.c | 46 +++++++++++++++++++++++++++++---------------- src/ca65/main.c | 18 +++++++++--------- src/ca65/sizeof.c | 3 +++ src/ca65/symbol.c | 4 ++-- src/ca65/symentry.c | 22 +++------------------- src/ca65/symentry.h | 14 ++++---------- src/ca65/symtab.c | 8 ++++---- 7 files changed, 55 insertions(+), 60 deletions(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index b74e23fc8..171ab44c7 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -394,25 +394,39 @@ static ExprNode* FuncSizeOf (void) long Size; - /* Parse the scope and the name */ - SymTable* ParentScope = ParseScopedIdent (Name, &FullName); + if (Tok == TOK_LOCAL_IDENT) { - /* Check if the parent scope is valid */ - if (ParentScope == 0) { - /* No such scope */ - DoneStrBuf (&FullName); - return GenLiteralExpr (0); - } + /* Cheap local symbol, special handling */ + Sym = SymFindLocal (SymLast, SVal, SYM_FIND_EXISTING); + if (Sym == 0) { + Error ("Unknown symbol or scope: `%s'", SB_GetConstBuf (&FullName)); + return GenLiteralExpr (0); + } else { + SizeSym = GetSizeOfSymbol (Sym); + } - /* The scope is valid, search first for a child scope, then for a symbol */ - if ((Scope = SymFindScope (ParentScope, Name, SYM_FIND_EXISTING)) != 0) { - /* Yep, it's a scope */ - SizeSym = GetSizeOfScope (Scope); - } else if ((Sym = SymFind (ParentScope, Name, SYM_FIND_EXISTING)) != 0) { - SizeSym = GetSizeOfSymbol (Sym); } else { - Error ("Unknown symbol or scope: `%s'", SB_GetConstBuf (&FullName)); - return GenLiteralExpr (0); + + /* Parse the scope and the name */ + SymTable* ParentScope = ParseScopedIdent (Name, &FullName); + + /* Check if the parent scope is valid */ + if (ParentScope == 0) { + /* No such scope */ + DoneStrBuf (&FullName); + return GenLiteralExpr (0); + } + + /* The scope is valid, search first for a child scope, then for a symbol */ + if ((Scope = SymFindScope (ParentScope, Name, SYM_FIND_EXISTING)) != 0) { + /* Yep, it's a scope */ + SizeSym = GetSizeOfScope (Scope); + } else if ((Sym = SymFind (ParentScope, Name, SYM_FIND_EXISTING)) != 0) { + SizeSym = GetSizeOfSymbol (Sym); + } else { + Error ("Unknown symbol or scope: `%s'", SB_GetConstBuf (&FullName)); + return GenLiteralExpr (0); + } } /* Check if we have a size */ diff --git a/src/ca65/main.c b/src/ca65/main.c index 0b40393f7..dc77a2e92 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -374,7 +374,7 @@ static void DoPCAssign (void) static void OneLine (void) /* Assemble one line */ -{ +{ Segment* Seg = 0; unsigned long PC = 0; SymEntry* Sym = 0; @@ -463,14 +463,14 @@ static void OneLine (void) NextTok (); if (Tok != TOK_EQ) { Error ("`=' expected"); - SkipUntilSep (); - } else { - /* Skip the equal sign */ - NextTok (); - /* Enter absolute mode */ - DoPCAssign (); - } - } + SkipUntilSep (); + } else { + /* Skip the equal sign */ + NextTok (); + /* Enter absolute mode */ + DoPCAssign (); + } + } /* If we have defined a label, remember its size. Sym is also set by * a symbol assignment, but in this case Done is false, so we don't diff --git a/src/ca65/sizeof.c b/src/ca65/sizeof.c index ae2210a04..1c63efd46 100644 --- a/src/ca65/sizeof.c +++ b/src/ca65/sizeof.c @@ -37,6 +37,7 @@ #include "addrsize.h" /* ca65 */ +#include "expr.h" #include "sizeof.h" #include "symtab.h" @@ -88,6 +89,7 @@ SymEntry* DefSizeOfScope (SymTable* Scope, long Size) { SymEntry* SizeSym = GetSizeOfScope (Scope); SymDef (SizeSym, GenLiteralExpr (Size), ADDR_SIZE_DEFAULT, SF_NONE); + return SizeSym; } @@ -97,6 +99,7 @@ SymEntry* DefSizeOfSymbol (SymEntry* Sym, long Size) { SymEntry* SizeSym = GetSizeOfSymbol (Sym); SymDef (SizeSym, GenLiteralExpr (Size), ADDR_SIZE_DEFAULT, SF_NONE); + return SizeSym; } diff --git a/src/ca65/symbol.c b/src/ca65/symbol.c index abc371a25..e4c46136d 100644 --- a/src/ca65/symbol.c +++ b/src/ca65/symbol.c @@ -145,7 +145,7 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* FullName) NextTok (); } } - + SymEntry* ParseScopedSymName (int AllocNew) @@ -174,7 +174,7 @@ SymEntry* ParseScopedSymName (int AllocNew) * symbol. */ if (AllocNew) { - return NewSymEntry (Ident); + return NewSymEntry (Ident, SF_NONE); } else { return 0; } diff --git a/src/ca65/symentry.c b/src/ca65/symentry.c index ee137b9e9..124ad7d9e 100644 --- a/src/ca65/symentry.c +++ b/src/ca65/symentry.c @@ -72,23 +72,7 @@ SymEntry* SymLast = 0; -int IsLocalName (const char* Name) -/* Return true if Name is the name of a local symbol */ -{ - return (*Name == LocalStart); -} - - - -int IsLocalNameId (unsigned Name) -/* Return true if Name is the name of a local symbol */ -{ - return (*GetString (Name) == LocalStart); -} - - - -SymEntry* NewSymEntry (const char* Name) +SymEntry* NewSymEntry (const char* Name, unsigned Flags) /* Allocate a symbol table entry, initialize and return it */ { /* Allocate memory */ @@ -100,7 +84,7 @@ SymEntry* NewSymEntry (const char* Name) S->Locals = 0; S->SymTab = 0; S->Pos = CurPos; - S->Flags = 0; + S->Flags = Flags; S->V.Expr = 0; S->ExprRefs = AUTO_COLLECTION_INITIALIZER; S->ExportSize = ADDR_SIZE_DEFAULT; @@ -243,7 +227,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags } /* If this is not a local symbol, remember it as the last global one */ - if (!IsLocalNameId (S->Name)) { + if ((S->Flags & SF_LOCAL) == 0) { SymLast = S; } } diff --git a/src/ca65/symentry.h b/src/ca65/symentry.h index ce342a830..2f5324ede 100644 --- a/src/ca65/symentry.h +++ b/src/ca65/symentry.h @@ -62,6 +62,7 @@ #define SF_EXPORT 0x0004 /* Export this symbol */ #define SF_IMPORT 0x0008 /* Import this symbol */ #define SF_GLOBAL 0x0010 /* Global symbol */ +#define SF_LOCAL 0x0020 /* Cheap local symbol */ #define SF_LABEL 0x0080 /* Used as a label */ #define SF_FORCED 0x0100 /* Forced import, SF_IMPORT also set */ #define SF_INDEXED 0x0800 /* Index is valid */ @@ -85,14 +86,13 @@ struct SymEntry { unsigned Flags; /* Symbol flags */ unsigned Index; /* Index of import/export entries */ union { - struct ExprNode* Expr; /* Expression if CONST not set */ - long Val; /* Value (if CONST set) */ + struct ExprNode* Expr; /* Symbol expression */ SymEntry* Sym; /* Symbol (if trampoline entry) */ } V; Collection ExprRefs; /* Expressions using this symbol */ unsigned char ExportSize; /* Export address size */ unsigned char AddrSize; /* Address size of label */ - unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */ + unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */ /* ...actually value+1 (used as flag) */ unsigned Name; /* Name index in global string pool */ }; @@ -111,13 +111,7 @@ extern SymEntry* SymLast; -int IsLocalName (const char* Name); -/* Return true if Name is the name of a local symbol */ - -int IsLocalNameId (unsigned Name); -/* Return true if Name is the name of a local symbol */ - -SymEntry* NewSymEntry (const char* Name); +SymEntry* NewSymEntry (const char* Name, unsigned Flags); /* Allocate a symbol table entry, initialize and return it */ int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E); diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 914ed1cc6..4fab0d7bc 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -269,7 +269,7 @@ SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew) /* No last global, so there's no local table */ Error ("No preceeding global symbol"); if (AllocNew) { - return NewSymEntry (Name); + return NewSymEntry (Name, SF_LOCAL); } else { return 0; } @@ -286,7 +286,7 @@ SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew) if (AllocNew) { /* Otherwise create a new entry, insert and return it */ - SymEntry* N = NewSymEntry (Name); + SymEntry* N = NewSymEntry (Name, SF_LOCAL); if (S == 0) { Parent->Locals = N; } else if (Cmp < 0) { @@ -325,7 +325,7 @@ SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew) if (AllocNew) { /* Otherwise create a new entry, insert and return it */ - SymEntry* N = NewSymEntry (Name); + SymEntry* N = NewSymEntry (Name, SF_NONE); if (S == 0) { Scope->Table[Hash] = N; } else if (Cmp < 0) { @@ -377,7 +377,7 @@ int SymIsZP (SymEntry* S) * enclosing scope for a symbol with the same name, and return the ZP * attribute of this symbol if we find one. */ - if (!IsLocalNameId (S->Name) && (S->Flags & (SF_DEFINED | SF_IMPORT)) == 0 && + if ((S->Flags & (SF_DEFINED | SF_IMPORT | SF_LOCAL)) == 0 && S->SymTab->Parent != 0) { /* Try to find a symbol with the same name in the enclosing scope */