]> git.sur5r.net Git - cc65/commitdiff
More .size/.sizeof support
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 30 Nov 2003 18:41:32 +0000 (18:41 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 30 Nov 2003 18:41:32 +0000 (18:41 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2699 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/expr.c
src/ca65/main.c
src/ca65/make/gcc.mak
src/ca65/make/watcom.mak
src/ca65/sizeof.c [new file with mode: 0644]
src/ca65/sizeof.h [new file with mode: 0644]
src/ca65/struct.c
src/ca65/symtab.c
src/ca65/symtab.h

index 3af3ea3099f245b6cc5e79d7b39ae70b853b9eea..f8e80be480e65594243548f6ea271fb6c93e2754 100644 (file)
@@ -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;
 
index 9a159a1a4332a569f05a66237190a9abdf7103a4..69f9ec00d16ff4ea89568da8569dffa6967ceda7 100644 (file)
@@ -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 ();
 
index 2d3669649180edfa828853d1364e52b5fb4b1210..87c6b169200634d8777dd24c816913c88a268fb2 100644 (file)
@@ -38,6 +38,7 @@ OBJS =  anonname.o      \
        repeat.o        \
         scanner.o      \
         segment.o       \
+        sizeof.o        \
         spool.o         \
         struct.o        \
         studyexpr.o     \
index f9e73406ccd3292a04ae585053169883583ea0a0..d8b294a8de6b963cb3e58a2c462e77d524baf3f6 100644 (file)
@@ -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 (file)
index 0000000..5e2b7b7
--- /dev/null
@@ -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 (file)
index 0000000..26794cb
--- /dev/null
@@ -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
+
+
+
index 0ee0752fb5474e0b3aae11850dda4b907cdc6e9f..99154c73e7050083c44bc06d5aa4bb75f483f740 100644 (file)
@@ -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 */
index 674d925907d95d97575f7d4167ebeba175251ac6..914ed1cc696e56a3484115df78241cbabbf3dfd1 100644 (file)
@@ -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 {
index bc32a2c793ed7f481b0304d4fa5aa8c9e0f5ac8e..48b34847459be3cb1375f2fc1b6aa21dff2c1b63 100644 (file)
@@ -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.