mirror of
https://github.com/cc65/cc65.git
synced 2024-12-27 00:29:31 +00:00
More work on .sizeof, fixed problems with cheap locals
git-svn-id: svn://svn.cc65.org/cc65/trunk@2704 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
500f6c994a
commit
14d0577ef0
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user