From cf7b4e227a5e136cbd7e1ab08888136801dc81f6 Mon Sep 17 00:00:00 2001 From: cuz Date: Sun, 30 Nov 2003 18:41:32 +0000 Subject: [PATCH] More .size/.sizeof support git-svn-id: svn://svn.cc65.org/cc65/trunk@2699 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/expr.c | 55 ++++++++++++--------------- src/ca65/main.c | 2 +- src/ca65/make/gcc.mak | 1 + src/ca65/make/watcom.mak | 1 + src/ca65/sizeof.c | 82 ++++++++++++++++++++++++++++++++++++++++ src/ca65/sizeof.h | 75 ++++++++++++++++++++++++++++++++++++ src/ca65/struct.c | 10 ++++- src/ca65/symtab.c | 8 ++-- src/ca65/symtab.h | 2 +- 9 files changed, 198 insertions(+), 38 deletions(-) create mode 100644 src/ca65/sizeof.c create mode 100644 src/ca65/sizeof.h diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 3af3ea309..f8e80be48 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -54,7 +54,7 @@ #include "nexttok.h" #include "objfile.h" #include "segment.h" -#include "struct.h" +#include "sizeof.h" #include "studyexpr.h" #include "symbol.h" #include "symtab.h" @@ -195,6 +195,27 @@ static int IsEasyConst (const ExprNode* E, long* Val) +static ExprNode* Symbol (SymEntry* S) +/* Reference a symbol and return an expression for it */ +{ + if (S == 0) { + /* Some weird error happened before */ + return GenLiteralExpr (0); + } else { + /* Mark the symbol as referenced */ + SymRef (S); + /* Remove the symbol if possible */ + if (SymHasExpr (S)) { + return CloneExpr (GetSymExpr (S)); + } else { + /* Create symbol node */ + return GenSymExpr (S); + } + } +} + + + static ExprNode* FuncBlank (void) /* Handle the .BLANK builtin function */ { @@ -369,21 +390,16 @@ static ExprNode* FuncReferenced (void) static ExprNode* FuncSizeOf (void) /* Handle the .SIZEOF function */ { - long Size; - /* Get the struct for the scoped struct name */ SymTable* Struct = ParseScopedSymTable (SYM_FIND_EXISTING); /* Check if the given symbol is really a struct */ if (GetSymTabType (Struct) != ST_STRUCT) { Error ("Argument to .SIZEOF is not a struct"); - Size = 1; + return GenLiteralExpr (0); } else { - Size = GetStructSize (Struct); + return Symbol (GetSizeOfScope (Struct)); } - - /* Return the size */ - return GenLiteralExpr (Size); } @@ -534,27 +550,6 @@ static ExprNode* Function (ExprNode* (*F) (void)) -static ExprNode* Symbol (SymEntry* S) -/* Reference a symbol and return an expression for it */ -{ - if (S == 0) { - /* Some weird error happened before */ - return GenLiteralExpr (0); - } else { - /* Mark the symbol as referenced */ - SymRef (S); - /* Remove the symbol if possible */ - if (SymHasExpr (S)) { - return CloneExpr (GetSymExpr (S)); - } else { - /* Create symbol node */ - return GenSymExpr (S); - } - } -} - - - static ExprNode* Factor (void) { ExprNode* L; @@ -579,7 +574,7 @@ static ExprNode* Factor (void) break; case TOK_LOCAL_IDENT: - N = Symbol (SymFindLocal (SVal, SYM_ALLOC_NEW)); + N = Symbol (SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW)); NextTok (); break; diff --git a/src/ca65/main.c b/src/ca65/main.c index 9a159a1a4..69f9ec00d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -400,7 +400,7 @@ static void OneLine (void) if (Tok == TOK_IDENT) { Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW); } else { - Sym = SymFindLocal (SVal, SYM_ALLOC_NEW); + Sym = SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW); } NextTok (); diff --git a/src/ca65/make/gcc.mak b/src/ca65/make/gcc.mak index 2d3669649..87c6b1692 100644 --- a/src/ca65/make/gcc.mak +++ b/src/ca65/make/gcc.mak @@ -38,6 +38,7 @@ OBJS = anonname.o \ repeat.o \ scanner.o \ segment.o \ + sizeof.o \ spool.o \ struct.o \ studyexpr.o \ diff --git a/src/ca65/make/watcom.mak b/src/ca65/make/watcom.mak index f9e73406c..d8b294a8d 100644 --- a/src/ca65/make/watcom.mak +++ b/src/ca65/make/watcom.mak @@ -87,6 +87,7 @@ OBJS = anonname.obj \ repeat.obj \ scanner.obj \ segment.obj \ + sizeof.obj \ spool.obj \ struct.obj \ studyexpr.obj \ diff --git a/src/ca65/sizeof.c b/src/ca65/sizeof.c new file mode 100644 index 000000000..5e2b7b7d5 --- /dev/null +++ b/src/ca65/sizeof.c @@ -0,0 +1,82 @@ +/*****************************************************************************/ +/* */ +/* sizeof.c */ +/* */ +/* Handle sizes of types and data */ +/* */ +/* */ +/* */ +/* (C) 2003 Ullrich von Bassewitz */ +/* Römerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +/* ca65 */ +#include "sizeof.h" +#include "symtab.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* The name of the symbol used to encode the size. The name of this entry is + * choosen so that it cannot be accessed by the user. + */ +static const char SizeEntryName[] = ".size"; + + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +SymEntry* GetSizeOfScope (SymTable* Scope) +/* Get the size of a scope. The function returns the symbol table entry that + * encodes the size, and will create a new entry if it does not exist. + */ +{ + return SymFind (Scope, SizeEntryName, SYM_ALLOC_NEW); +} + + + +SymEntry* GetSizeOfSymbol (SymEntry* Sym) +/* Get the size of a symbol table entry. The function returns the symbol table + * entry that encodes the size of the symbol and will create a new one if it + * does not exist. + */ +{ + return SymFindLocal (Sym, SizeEntryName, SYM_ALLOC_NEW); +} + + + diff --git a/src/ca65/sizeof.h b/src/ca65/sizeof.h new file mode 100644 index 000000000..26794cb26 --- /dev/null +++ b/src/ca65/sizeof.h @@ -0,0 +1,75 @@ +/*****************************************************************************/ +/* */ +/* sizeof.h */ +/* */ +/* Handle sizes of types and data */ +/* */ +/* */ +/* */ +/* (C) 2003 Ullrich von Bassewitz */ +/* Römerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef SIZEOF_H +#define SIZEOF_H + + + +/*****************************************************************************/ +/* Forwards */ +/*****************************************************************************/ + + + +struct SymEntry; +struct SymTable; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +struct SymEntry* GetSizeOfScope (struct SymTable* Scope); +/* Get the size of a scope. The function returns the symbol table entry that + * encodes the size, and will create a new entry if it does not exist. + */ + +struct SymEntry* GetSizeOfSymbol (struct SymEntry* Sym); +/* Get the size of a symbol table entry. The function returns the symbol table + * entry that encodes the size of the symbol and will create a new one if it + * does not exist. + */ + + + +/* End of sizeof.h */ +#endif + + + diff --git a/src/ca65/struct.c b/src/ca65/struct.c index 0ee0752fb..99154c73e 100644 --- a/src/ca65/struct.c +++ b/src/ca65/struct.c @@ -42,6 +42,7 @@ #include "expr.h" #include "nexttok.h" #include "scanner.h" +#include "sizeof.h" #include "symbol.h" #include "symtab.h" #include "struct.h" @@ -173,7 +174,12 @@ static long DoStructInternal (long Offs, unsigned Type) } else if (GetSymTabType (Struct) != ST_STRUCT) { Error ("Not a struct/union"); } else { - MemberSize = Member (GetStructSize (Struct)); + SymEntry* SizeSym = GetSizeOfScope (Struct); + if (!SymIsDef (SizeSym)) { + Error ("Size of struct/union is unknown"); + } else { + MemberSize = GetSymVal (SizeSym); + } } break; @@ -218,7 +224,7 @@ static long DoStructInternal (long Offs, unsigned Type) */ if (!Anon) { /* Add a symbol */ - SymEntry* SizeSym = SymFind (CurrentScope, ".size", SYM_ALLOC_NEW); + SymEntry* SizeSym = GetSizeOfScope (CurrentScope); SymDef (SizeSym, GenLiteralExpr (Size), ADDR_SIZE_DEFAULT, SF_NONE); /* Close the struct scope */ diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 674d92590..914ed1cc6 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -255,7 +255,7 @@ SymTable* SymFindAnyScope (SymTable* Parent, const char* Name) -SymEntry* SymFindLocal (const char* Name, int AllocNew) +SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew) /* Find a cheap local symbol. If AllocNew is given and the entry is not * found, create a new one. Return the entry found, or the new entry created, * or - in case AllocNew is zero - return 0. @@ -265,7 +265,7 @@ SymEntry* SymFindLocal (const char* Name, int AllocNew) int Cmp; /* Local symbol, get the table */ - if (!SymLast) { + if (!Parent) { /* No last global, so there's no local table */ Error ("No preceeding global symbol"); if (AllocNew) { @@ -276,7 +276,7 @@ SymEntry* SymFindLocal (const char* Name, int AllocNew) } /* Search for the symbol if we have a table */ - Cmp = SymSearchTree (SymLast->Locals, Name, &S); + Cmp = SymSearchTree (Parent->Locals, Name, &S); /* If we found an entry, return it */ if (Cmp == 0) { @@ -288,7 +288,7 @@ SymEntry* SymFindLocal (const char* Name, int AllocNew) /* Otherwise create a new entry, insert and return it */ SymEntry* N = NewSymEntry (Name); if (S == 0) { - SymLast->Locals = N; + Parent->Locals = N; } else if (Cmp < 0) { S->Left = N; } else { diff --git a/src/ca65/symtab.h b/src/ca65/symtab.h index bc32a2c79..48b348474 100644 --- a/src/ca65/symtab.h +++ b/src/ca65/symtab.h @@ -111,7 +111,7 @@ SymTable* SymFindAnyScope (SymTable* Parent, const char* Name); * scope. */ -SymEntry* SymFindLocal (const char* Name, int AllocNew); +SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew); /* Find a cheap local symbol. If AllocNew is given and the entry is not * found, create a new one. Return the entry found, or the new entry created, * or - in case AllocNew is zero - return 0. -- 2.39.5