/* */
/* */
/* */
-/* (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"
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
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) {
- Error ("Range error");
+ ErrorSkip ("Range error");
}
/* Return the size */
long Size = 0;
/* Outside of other structs, we need a name. Inside another struct or
- * union, the struct may be anonymous, in which case no new lexical level
- * is started.
- */
- int Anon = (Tok != TOK_IDENT);
+ ** union, the struct may be anonymous, in which case no new lexical level
+ ** is started.
+ */
+ 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;
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);
/* Read storage allocators */
MemberSize = 0; /* In case of errors, use zero */
- switch (Tok) {
+ switch (CurTok.Tok) {
case TOK_BYTE:
NextTok ();
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);
}
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) || !SymIsConst (SizeSym, &MemberSize)) {
- Error ("Size of struct/union is unknown");
+ ErrorSkip ("Size of struct/union is unknown");
}
}
- MemberSize *= Member (MemberSize);
+ MemberSize = Member (MemberSize);
break;
case TOK_STRUCT:
}
/* If this is not a anon struct, enter a special symbol named ".size"
- * into the symbol table of the struct that holds the size of the
- * struct. Since the symbol starts with a dot, it cannot be accessed
- * by user code.
- * Leave the struct scope level.
- */
+ ** into the symbol table of the struct that holds the size of the
+ ** struct. Since the symbol starts with a dot, it cannot be accessed
+ ** by user code.
+ ** Leave the struct scope level.
+ */
if (!Anon) {
/* Add a symbol */
SymEntry* SizeSym = GetSizeOfScope (CurrentScope);
/* End of struct/union definition */
if (Type == STRUCT) {
- Consume (TOK_ENDSTRUCT, "`.ENDSTRUCT' expected");
+ Consume (TOK_ENDSTRUCT, "'.ENDSTRUCT' expected");
} else {
- Consume (TOK_ENDUNION, "`.ENDUNION' expected");
+ Consume (TOK_ENDUNION, "'.ENDUNION' expected");
}
/* Return the size of the struct */
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);
}
}
{
DoStructInternal (0, UNION);
}
-
-
-