]> git.sur5r.net Git - cc65/blobdiff - src/ca65/struct.c
Renamed variables for better readability.
[cc65] / src / ca65 / struct.c
index 307171d8a26d188f800af506b3fa0823b6f6ed79..07068ef947464520949abc8a4c39d3e7af7da381 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2003      Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2003-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 /* common */
 #include "addrsize.h"
+#include "scopedefs.h"
 
 /* ca65 */
 #include "condasm.h"
 #include "error.h"
 #include "expr.h"
+#include "macro.h"
 #include "nexttok.h"
 #include "scanner.h"
 #include "sizeof.h"
@@ -74,15 +76,20 @@ static long Member (long AllocSize)
     long Multiplicator;
 
     /* A multiplicator may follow */
-    if (Tok != TOK_SEP) {
+    if (CurTok.Tok != TOK_SEP) {
         Multiplicator = ConstExpression ();
         if (Multiplicator <= 0) {
-            Error ("Range error");
+            ErrorSkip ("Range error");
             Multiplicator = 1;
         }
         AllocSize *= Multiplicator;
     }
 
+    /* Check the size for a reasonable value */
+    if (AllocSize >= 0x10000) {
+        ErrorSkip ("Range error");
+    }
+
     /* Return the size */
     return AllocSize;
 }
@@ -98,16 +105,10 @@ static long DoStructInternal (long Offs, unsigned Type)
      * union, the struct may be anonymous, in which case no new lexical level
      * is started.
      */
-    int Anon = (Tok != TOK_IDENT);
-    if (Anon) {
-        unsigned char T = GetCurrentSymTabType ();
-        if (T != ST_STRUCT) {
-            ErrorSkip ("Struct/union needs a name");
-            return 0;
-        }
-    } else {
+    int Anon = (CurTok.Tok != TOK_IDENT);
+    if (!Anon) {
         /* Enter a new scope, then skip the name */
-        SymEnterLevel (SVal, ST_STRUCT, ADDR_SIZE_ABS);
+        SymEnterLevel (&CurTok.SVal, SCOPE_STRUCT, ADDR_SIZE_ABS, 0);
         NextTok ();
         /* Start at zero offset in the new scope */
         Offs = 0;
@@ -117,16 +118,35 @@ static long DoStructInternal (long Offs, unsigned Type)
     ConsumeSep ();
 
     /* Read until end of struct */
-    while (Tok != TOK_ENDSTRUCT && Tok != TOK_ENDUNION && Tok != TOK_EOF) {
+    while (CurTok.Tok != TOK_ENDSTRUCT &&
+           CurTok.Tok != TOK_ENDUNION  &&
+           CurTok.Tok != TOK_EOF) {
 
         long      MemberSize;
         SymTable* Struct;
+        SymEntry* Sym;
+
+        /* Allow empty and comment lines */
+        if (CurTok.Tok == TOK_SEP) {
+            NextTok ();
+            continue;
+        }
 
         /* The format is "[identifier] storage-allocator [, multiplicator]" */
-        SymEntry* Sym = 0;
-        if (Tok == TOK_IDENT) {
+        Sym = 0;
+        if (CurTok.Tok == TOK_IDENT) {
+
+            /* Beware: An identifier may also be a macro, in which case we have
+             * to start over.
+             */
+            Macro* M = FindMacro (&CurTok.SVal);
+            if (M) {
+                MacExpandStart (M);
+                continue;
+            }
+
             /* We have an identifier, generate a symbol */
-            Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
+            Sym = SymFind (CurrentScope, &CurTok.SVal, SYM_ALLOC_NEW);
 
             /* Assign the symbol the offset of the current member */
             SymDef (Sym, GenLiteralExpr (Offs), ADDR_SIZE_DEFAULT, SF_NONE);
@@ -137,7 +157,7 @@ static long DoStructInternal (long Offs, unsigned Type)
 
         /* Read storage allocators */
         MemberSize = 0;                 /* In case of errors, use zero */
-        switch (Tok) {
+        switch (CurTok.Tok) {
 
             case TOK_BYTE:
                 NextTok ();
@@ -162,8 +182,9 @@ static long DoStructInternal (long Offs, unsigned Type)
                 break;
 
             case TOK_RES:
-                if (Tok == TOK_SEP) {
-                    Error ("Size is missing");
+               NextTok ();
+                if (CurTok.Tok == TOK_SEP) {
+                    ErrorSkip ("Size is missing");
                 } else {
                     MemberSize = Member (1);
                 }
@@ -173,18 +194,16 @@ static long DoStructInternal (long Offs, unsigned Type)
                 NextTok ();
                 Struct = ParseScopedSymTable ();
                 if (Struct == 0) {
-                    Error ("Unknown struct/union");
-                } else if (GetSymTabType (Struct) != ST_STRUCT) {
-                    Error ("Not a struct/union");
+                    ErrorSkip ("Unknown struct/union");
+                } else if (GetSymTabType (Struct) != SCOPE_STRUCT) {
+                    ErrorSkip ("Not a struct/union");
                 } else {
                     SymEntry* SizeSym = GetSizeOfScope (Struct);
-                    if (!SymIsDef (SizeSym)) {
-                        Error ("Size of struct/union is unknown");
-                    } else {
-                        MemberSize = GetSymVal (SizeSym);
+                    if (!SymIsDef (SizeSym) || !SymIsConst (SizeSym, &MemberSize)) {
+                        ErrorSkip ("Size of struct/union is unknown");
                     }
                 }
-                MemberSize *= Member (MemberSize);
+                MemberSize = Member (MemberSize);
                 break;
 
             case TOK_STRUCT:
@@ -256,12 +275,12 @@ static long DoStructInternal (long Offs, unsigned Type)
 long GetStructSize (SymTable* Struct)
 /* Get the size of a struct or union */
 {
-    SymEntry* Sym = SymFind (Struct, ".size", SYM_FIND_EXISTING);
-    if (Sym == 0) {
+    SymEntry* SizeSym = FindSizeOfScope (Struct);
+    if (SizeSym == 0) {
         Error ("Size of struct/union is unknown");
         return 0;
     } else {
-        return GetSymVal (Sym);
+        return GetSymVal (SizeSym);
     }
 }