]> git.sur5r.net Git - cc65/blobdiff - src/ca65/struct.c
More lineinfo usage.
[cc65] / src / ca65 / struct.c
index cb757e0a07af3eaf5d6010aff51656010301653f..56b9856f4a071065b7ed03a8ccd794543956ce8b 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       */
@@ -73,17 +73,21 @@ static long Member (long AllocSize)
 {
     long Multiplicator;
 
-    /* A comma and a multiplicator may follow */
-    if (Tok == TOK_COMMA) {
-        NextTok ();
+    /* A multiplicator may follow */
+    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;
 }
@@ -99,16 +103,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, ST_STRUCT, ADDR_SIZE_ABS);
         NextTok ();
         /* Start at zero offset in the new scope */
         Offs = 0;
@@ -118,16 +116,25 @@ 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) {
             /* 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);
@@ -138,7 +145,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 ();
@@ -163,24 +170,28 @@ static long DoStructInternal (long Offs, unsigned Type)
                 break;
 
             case TOK_RES:
-                Error ("Not implemented");
+               NextTok ();
+                if (CurTok.Tok == TOK_SEP) {
+                    ErrorSkip ("Size is missing");
+                } else {
+                    MemberSize = Member (1);
+                }
                 break;
 
             case TOK_TAG:
                 NextTok ();
                 Struct = ParseScopedSymTable ();
                 if (Struct == 0) {
-                    Error ("Unknown struct/union");
+                    ErrorSkip ("Unknown struct/union");
                 } else if (GetSymTabType (Struct) != ST_STRUCT) {
-                    Error ("Not a struct/union");
+                    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);
                 break;
 
             case TOK_STRUCT:
@@ -252,7 +263,7 @@ 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);
+    SymEntry* Sym = SymFind (Struct, &SizeEntryName, SYM_FIND_EXISTING);
     if (Sym == 0) {
         Error ("Size of struct/union is unknown");
         return 0;