mirror of
https://github.com/cc65/cc65.git
synced 2025-02-06 12:31:12 +00:00
Added flexible array members for structs
git-svn-id: svn://svn.cc65.org/cc65/trunk@1925 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
d5481ff95b
commit
c123666d24
@ -6,9 +6,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2002 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
@ -4013,10 +4013,12 @@ void g_defbytes (const void* Bytes, unsigned Count)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void g_zerobytes (unsigned n)
|
void g_zerobytes (unsigned Count)
|
||||||
/* Output n bytes of data initialized with zero */
|
/* Output Count bytes of data initialized with zero */
|
||||||
{
|
{
|
||||||
AddDataLine ("\t.res\t%u,$00", n);
|
if (Count > 0) {
|
||||||
|
AddDataLine ("\t.res\t%u,$00", Count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2002 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
@ -432,8 +432,8 @@ void g_defdata (unsigned flags, unsigned long val, long offs);
|
|||||||
void g_defbytes (const void* bytes, unsigned count);
|
void g_defbytes (const void* bytes, unsigned count);
|
||||||
/* Output a row of bytes as a constant */
|
/* Output a row of bytes as a constant */
|
||||||
|
|
||||||
void g_zerobytes (unsigned n);
|
void g_zerobytes (unsigned Count);
|
||||||
/* Output n bytes of data initialized with zero */
|
/* Output Count bytes of data initialized with zero */
|
||||||
|
|
||||||
void g_initregister (unsigned Label, unsigned Reg, unsigned Size);
|
void g_initregister (unsigned Label, unsigned Reg, unsigned Size);
|
||||||
/* Initialize a register variable from static initialization data */
|
/* Initialize a register variable from static initialization data */
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2002 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@musoftware.de */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
@ -368,7 +368,7 @@ void PrintRawType (FILE* F, const type* Type)
|
|||||||
|
|
||||||
|
|
||||||
void Encode (type* Type, unsigned long Val)
|
void Encode (type* Type, unsigned long Val)
|
||||||
/* Encode p[0] and p[1] so that neither p[0] nore p[1] is zero */
|
/* Encode Val into the given type string */
|
||||||
{
|
{
|
||||||
int I;
|
int I;
|
||||||
for (I = 0; I < DECODE_SIZE; ++I) {
|
for (I = 0; I < DECODE_SIZE; ++I) {
|
||||||
@ -429,6 +429,7 @@ unsigned SizeOf (const type* T)
|
|||||||
/* Compute size of object represented by type array. */
|
/* Compute size of object represented by type array. */
|
||||||
{
|
{
|
||||||
SymEntry* Entry;
|
SymEntry* Entry;
|
||||||
|
long ElementCount;
|
||||||
|
|
||||||
switch (UnqualifiedType (T[0])) {
|
switch (UnqualifiedType (T[0])) {
|
||||||
|
|
||||||
@ -470,11 +471,17 @@ unsigned SizeOf (const type* T)
|
|||||||
|
|
||||||
case T_STRUCT:
|
case T_STRUCT:
|
||||||
case T_UNION:
|
case T_UNION:
|
||||||
Entry = (SymEntry*) DecodePtr (T+1);
|
Entry = DecodePtr (T+1);
|
||||||
return Entry->V.S.Size;
|
return Entry->V.S.Size;
|
||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
return (Decode (T+ 1) * SizeOf (T + DECODE_SIZE + 1));
|
ElementCount = GetElementCount (T);
|
||||||
|
if (ElementCount < 0) {
|
||||||
|
/* Array with unspecified size */
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return ElementCount * SizeOf (T + DECODE_SIZE + 1);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("Unknown type in SizeOf: %04X", *T);
|
Internal ("Unknown type in SizeOf: %04X", *T);
|
||||||
@ -564,7 +571,7 @@ unsigned TypeOf (const type* T)
|
|||||||
return CF_LONG | CF_UNSIGNED;
|
return CF_LONG | CF_UNSIGNED;
|
||||||
|
|
||||||
case T_FUNC:
|
case T_FUNC:
|
||||||
F = (FuncDesc*) DecodePtr (T+1);
|
F = DecodePtr (T+1);
|
||||||
return (F->Flags & FD_VARIADIC)? 0 : CF_FIXARGC;
|
return (F->Flags & FD_VARIADIC)? 0 : CF_FIXARGC;
|
||||||
|
|
||||||
case T_STRUCT:
|
case T_STRUCT:
|
||||||
@ -714,7 +721,7 @@ FuncDesc* GetFuncDesc (const type* T)
|
|||||||
CHECK (T[0] == T_FUNC);
|
CHECK (T[0] == T_FUNC);
|
||||||
|
|
||||||
/* Decode the function descriptor and return it */
|
/* Decode the function descriptor and return it */
|
||||||
return (FuncDesc*) DecodePtr (T+1);
|
return DecodePtr (T+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -737,3 +744,14 @@ type* GetFuncReturn (type* T)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
long GetElementCount (const type* T)
|
||||||
|
/* Get the element count of the array specified in T (which must be of
|
||||||
|
* array type).
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
CHECK (IsTypeArray (T));
|
||||||
|
return (unsigned) Decode (T+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,6 +144,9 @@ typedef unsigned short type;
|
|||||||
/* Type elements needed for Encode/Decode */
|
/* Type elements needed for Encode/Decode */
|
||||||
#define DECODE_SIZE 5
|
#define DECODE_SIZE 5
|
||||||
|
|
||||||
|
/* Unspecified size for the element count of an array */
|
||||||
|
#define UNSPECIFIED -1L
|
||||||
|
|
||||||
/* Sizes */
|
/* Sizes */
|
||||||
#define SIZEOF_CHAR 1
|
#define SIZEOF_CHAR 1
|
||||||
#define SIZEOF_SHORT 2
|
#define SIZEOF_SHORT 2
|
||||||
@ -218,7 +221,7 @@ void PrintFuncSig (FILE* F, const char* Name, type* Type);
|
|||||||
/* Print a function signature. */
|
/* Print a function signature. */
|
||||||
|
|
||||||
void Encode (type* Type, unsigned long Val);
|
void Encode (type* Type, unsigned long Val);
|
||||||
/* Encode an unsigned long into a type array */
|
/* Encode Val into the given type string */
|
||||||
|
|
||||||
void EncodePtr (type* Type, void* P);
|
void EncodePtr (type* Type, void* P);
|
||||||
/* Encode a pointer into a type array */
|
/* Encode a pointer into a type array */
|
||||||
@ -474,6 +477,11 @@ FuncDesc* GetFuncDesc (const type* T) attribute ((const));
|
|||||||
type* GetFuncReturn (type* T) attribute ((const));
|
type* GetFuncReturn (type* T) attribute ((const));
|
||||||
/* Return a pointer to the return type of a function or pointer-to-function type */
|
/* Return a pointer to the return type of a function or pointer-to-function type */
|
||||||
|
|
||||||
|
long GetElementCount (const type* T);
|
||||||
|
/* Get the element count of the array specified in T (which must be of
|
||||||
|
* array type).
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of datatype.h */
|
/* End of datatype.h */
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@ -254,6 +254,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
|
|||||||
unsigned StructSize;
|
unsigned StructSize;
|
||||||
unsigned FieldSize;
|
unsigned FieldSize;
|
||||||
unsigned Offs;
|
unsigned Offs;
|
||||||
|
int FlexibleMember;
|
||||||
SymTable* FieldTab;
|
SymTable* FieldTab;
|
||||||
SymEntry* Entry;
|
SymEntry* Entry;
|
||||||
|
|
||||||
@ -283,6 +284,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
|
|||||||
EnterStructLevel ();
|
EnterStructLevel ();
|
||||||
|
|
||||||
/* Parse struct fields */
|
/* Parse struct fields */
|
||||||
|
FlexibleMember = 0;
|
||||||
StructSize = 0;
|
StructSize = 0;
|
||||||
while (CurTok.Tok != TOK_RCURLY) {
|
while (CurTok.Tok != TOK_RCURLY) {
|
||||||
|
|
||||||
@ -294,30 +296,55 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
|
|||||||
/* Read fields with this type */
|
/* Read fields with this type */
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* Get type and name of the struct field */
|
|
||||||
Declaration Decl;
|
Declaration Decl;
|
||||||
|
|
||||||
|
/* If we had a flexible array member before, no other fields can
|
||||||
|
* follow.
|
||||||
|
*/
|
||||||
|
if (FlexibleMember) {
|
||||||
|
Error ("Flexible array member must be last field");
|
||||||
|
FlexibleMember = 0; /* Avoid further errors */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get type and name of the struct field */
|
||||||
ParseDecl (&Spec, &Decl, 0);
|
ParseDecl (&Spec, &Decl, 0);
|
||||||
|
|
||||||
/* Get the offset of this field */
|
/* Get the offset of this field */
|
||||||
Offs = (StructType == T_STRUCT)? StructSize : 0;
|
Offs = (StructType == T_STRUCT)? StructSize : 0;
|
||||||
|
|
||||||
/* Add a field entry to the table */
|
/* Calculate the sizes, handle flexible array members */
|
||||||
AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, Offs);
|
|
||||||
|
|
||||||
/* Calculate offset of next field/size of the union */
|
|
||||||
FieldSize = CheckedSizeOf (Decl.Type);
|
|
||||||
if (StructType == T_STRUCT) {
|
if (StructType == T_STRUCT) {
|
||||||
/* It's a struct */
|
|
||||||
StructSize += FieldSize;
|
/* It's a struct. Check if this field is a flexible array
|
||||||
|
* member, and calculate the size of the field.
|
||||||
|
*/
|
||||||
|
if (IsTypeArray (Decl.Type) && GetElementCount (Decl.Type) == UNSPECIFIED) {
|
||||||
|
/* Array with unspecified size */
|
||||||
|
if (StructSize == 0) {
|
||||||
|
Error ("Flexible array member cannot be first struct field");
|
||||||
|
}
|
||||||
|
FlexibleMember = 1;
|
||||||
|
/* Assume zero for size calculations */
|
||||||
|
Encode (Decl.Type + 1, 0);
|
||||||
} else {
|
} else {
|
||||||
|
StructSize += CheckedSizeOf (Decl.Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
/* It's a union */
|
/* It's a union */
|
||||||
|
FieldSize = CheckedSizeOf (Decl.Type);
|
||||||
if (FieldSize > StructSize) {
|
if (FieldSize > StructSize) {
|
||||||
StructSize = FieldSize;
|
StructSize = FieldSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurTok.Tok != TOK_COMMA)
|
/* Add a field entry to the table */
|
||||||
|
AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, Offs);
|
||||||
|
|
||||||
|
if (CurTok.Tok != TOK_COMMA) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
NextToken ();
|
NextToken ();
|
||||||
}
|
}
|
||||||
ConsumeSemi ();
|
ConsumeSemi ();
|
||||||
@ -871,17 +898,17 @@ static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
|||||||
D->T += DECODE_SIZE;
|
D->T += DECODE_SIZE;
|
||||||
} else {
|
} else {
|
||||||
/* Array declaration */
|
/* Array declaration */
|
||||||
unsigned long Size = 0;
|
long Size = UNSPECIFIED;
|
||||||
NextToken ();
|
NextToken ();
|
||||||
/* Read the size if it is given */
|
/* Read the size if it is given */
|
||||||
if (CurTok.Tok != TOK_RBRACK) {
|
if (CurTok.Tok != TOK_RBRACK) {
|
||||||
ExprDesc lval;
|
ExprDesc lval;
|
||||||
ConstExpr (&lval);
|
ConstExpr (&lval);
|
||||||
if (lval.ConstVal < 0) {
|
if (lval.ConstVal <= 0) {
|
||||||
if (D->Ident[0] != '\0') {
|
if (D->Ident[0] != '\0') {
|
||||||
Error ("Size of array `%s' is negative", D->Ident);
|
Error ("Size of array `%s' is invalid", D->Ident);
|
||||||
} else {
|
} else {
|
||||||
Error ("Size of array is negative");
|
Error ("Size of array is invalid");
|
||||||
}
|
}
|
||||||
lval.ConstVal = 1;
|
lval.ConstVal = 1;
|
||||||
}
|
}
|
||||||
@ -978,16 +1005,21 @@ void CheckEmptyDecl (const DeclSpec* D)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ParseVoidInit (void)
|
static unsigned ParseVoidInit (void)
|
||||||
/* Parse an initialization of a void variable (special cc65 extension) */
|
/* Parse an initialization of a void variable (special cc65 extension).
|
||||||
|
* Return the number of bytes initialized.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
ExprDesc lval;
|
ExprDesc lval;
|
||||||
|
unsigned Size;
|
||||||
|
|
||||||
|
ConsumeLCurly ();
|
||||||
|
|
||||||
/* Allow an arbitrary list of values */
|
/* Allow an arbitrary list of values */
|
||||||
ConsumeLCurly ();
|
Size = 0;
|
||||||
do {
|
do {
|
||||||
ConstExpr (&lval);
|
ConstExpr (&lval);
|
||||||
switch (lval.Type[0]) {
|
switch (UnqualifiedType (lval.Type[0])) {
|
||||||
|
|
||||||
case T_SCHAR:
|
case T_SCHAR:
|
||||||
case T_UCHAR:
|
case T_UCHAR:
|
||||||
@ -996,6 +1028,7 @@ static void ParseVoidInit (void)
|
|||||||
lval.ConstVal &= 0xFF;
|
lval.ConstVal &= 0xFF;
|
||||||
}
|
}
|
||||||
DefineData (&lval);
|
DefineData (&lval);
|
||||||
|
Size += SIZEOF_CHAR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_SHORT:
|
case T_SHORT:
|
||||||
@ -1009,11 +1042,13 @@ static void ParseVoidInit (void)
|
|||||||
lval.ConstVal &= 0xFFFF;
|
lval.ConstVal &= 0xFFFF;
|
||||||
}
|
}
|
||||||
DefineData (&lval);
|
DefineData (&lval);
|
||||||
|
Size += SIZEOF_INT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
case T_ULONG:
|
case T_ULONG:
|
||||||
DefineData (&lval);
|
DefineData (&lval);
|
||||||
|
Size += SIZEOF_LONG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1029,22 +1064,31 @@ static void ParseVoidInit (void)
|
|||||||
|
|
||||||
} while (CurTok.Tok != TOK_RCURLY);
|
} while (CurTok.Tok != TOK_RCURLY);
|
||||||
|
|
||||||
|
/* Closing brace */
|
||||||
ConsumeRCurly ();
|
ConsumeRCurly ();
|
||||||
|
|
||||||
|
/* Return the number of bytes initialized */
|
||||||
|
return Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ParseStructInit (type* Type)
|
static unsigned ParseStructInit (type* Type)
|
||||||
/* Parse initialization of a struct or union */
|
/* Parse initialization of a struct or union. Return the number of data bytes. */
|
||||||
{
|
{
|
||||||
SymEntry* Entry;
|
SymEntry* Entry;
|
||||||
SymTable* Tab;
|
SymTable* Tab;
|
||||||
|
unsigned StructSize;
|
||||||
|
unsigned Size;
|
||||||
|
|
||||||
/* Consume the opening curly brace */
|
/* Consume the opening curly brace */
|
||||||
ConsumeLCurly ();
|
ConsumeLCurly ();
|
||||||
|
|
||||||
/* Get a pointer to the struct entry from the type */
|
/* Get a pointer to the struct entry from the type */
|
||||||
Entry = (SymEntry*) Decode (Type + 1);
|
Entry = DecodePtr (Type + 1);
|
||||||
|
|
||||||
|
/* Get the size of the struct from the symbol table entry */
|
||||||
|
StructSize = Entry->V.S.Size;
|
||||||
|
|
||||||
/* Check if this struct definition has a field table. If it doesn't, it
|
/* Check if this struct definition has a field table. If it doesn't, it
|
||||||
* is an incomplete definition.
|
* is an incomplete definition.
|
||||||
@ -1053,17 +1097,20 @@ static void ParseStructInit (type* Type)
|
|||||||
if (Tab == 0) {
|
if (Tab == 0) {
|
||||||
Error ("Cannot initialize variables with incomplete type");
|
Error ("Cannot initialize variables with incomplete type");
|
||||||
/* Returning here will cause lots of errors, but recovery is difficult */
|
/* Returning here will cause lots of errors, but recovery is difficult */
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a pointer to the list of symbols */
|
/* Get a pointer to the list of symbols */
|
||||||
Entry = Tab->SymHead;
|
Entry = Tab->SymHead;
|
||||||
|
|
||||||
|
/* Initialize fields */
|
||||||
|
Size = 0;
|
||||||
while (CurTok.Tok != TOK_RCURLY) {
|
while (CurTok.Tok != TOK_RCURLY) {
|
||||||
if (Entry == 0) {
|
if (Entry == 0) {
|
||||||
Error ("Too many initializers");
|
Error ("Too many initializers");
|
||||||
return;
|
return Size;
|
||||||
}
|
}
|
||||||
ParseInit (Entry->Type);
|
Size += ParseInit (Entry->Type);
|
||||||
Entry = Entry->NextSym;
|
Entry = Entry->NextSym;
|
||||||
if (CurTok.Tok != TOK_COMMA)
|
if (CurTok.Tok != TOK_COMMA)
|
||||||
break;
|
break;
|
||||||
@ -1074,22 +1121,25 @@ static void ParseStructInit (type* Type)
|
|||||||
ConsumeRCurly ();
|
ConsumeRCurly ();
|
||||||
|
|
||||||
/* If there are struct fields left, reserve additional storage */
|
/* If there are struct fields left, reserve additional storage */
|
||||||
while (Entry) {
|
if (Size < StructSize) {
|
||||||
g_zerobytes (CheckedSizeOf (Entry->Type));
|
g_zerobytes (StructSize - Size);
|
||||||
Entry = Entry->NextSym;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the number of bytes initialized */
|
||||||
|
return StructSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ParseInit (type* T)
|
unsigned ParseInit (type* T)
|
||||||
/* Parse initialization of variables. */
|
/* Parse initialization of variables. Return the number of data bytes. */
|
||||||
{
|
{
|
||||||
ExprDesc lval;
|
ExprDesc lval;
|
||||||
type* t;
|
type* t;
|
||||||
const char* str;
|
const char* str;
|
||||||
int Count;
|
int Count;
|
||||||
int Size;
|
long ElementCount;
|
||||||
|
unsigned ElementSize;
|
||||||
|
|
||||||
switch (UnqualifiedType (*T)) {
|
switch (UnqualifiedType (*T)) {
|
||||||
|
|
||||||
@ -1102,7 +1152,7 @@ void ParseInit (type* T)
|
|||||||
}
|
}
|
||||||
assignadjust (T, &lval);
|
assignadjust (T, &lval);
|
||||||
DefineData (&lval);
|
DefineData (&lval);
|
||||||
break;
|
return SIZEOF_CHAR;
|
||||||
|
|
||||||
case T_SHORT:
|
case T_SHORT:
|
||||||
case T_USHORT:
|
case T_USHORT:
|
||||||
@ -1116,7 +1166,7 @@ void ParseInit (type* T)
|
|||||||
}
|
}
|
||||||
assignadjust (T, &lval);
|
assignadjust (T, &lval);
|
||||||
DefineData (&lval);
|
DefineData (&lval);
|
||||||
break;
|
return SIZEOF_INT;
|
||||||
|
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
case T_ULONG:
|
case T_ULONG:
|
||||||
@ -1127,14 +1177,15 @@ void ParseInit (type* T)
|
|||||||
}
|
}
|
||||||
assignadjust (T, &lval);
|
assignadjust (T, &lval);
|
||||||
DefineData (&lval);
|
DefineData (&lval);
|
||||||
break;
|
return SIZEOF_LONG;
|
||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
Size = Decode (T + 1);
|
ElementCount = GetElementCount (T);
|
||||||
|
ElementSize = CheckedSizeOf (T + DECODE_SIZE + 1);
|
||||||
t = T + DECODE_SIZE + 1;
|
t = T + DECODE_SIZE + 1;
|
||||||
if (IsTypeChar (t) && CurTok.Tok == TOK_SCONST) {
|
if (IsTypeChar (t) && CurTok.Tok == TOK_SCONST) {
|
||||||
str = GetLiteral (CurTok.IVal);
|
str = GetLiteral (CurTok.IVal);
|
||||||
Count = strlen (str) + 1;
|
Count = GetLiteralPoolOffs () - CurTok.IVal;
|
||||||
TranslateLiteralPool (CurTok.IVal); /* Translate into target charset */
|
TranslateLiteralPool (CurTok.IVal); /* Translate into target charset */
|
||||||
g_defbytes (str, Count);
|
g_defbytes (str, Count);
|
||||||
ResetLiteralPoolOffs (CurTok.IVal); /* Remove string from pool */
|
ResetLiteralPoolOffs (CurTok.IVal); /* Remove string from pool */
|
||||||
@ -1151,34 +1202,33 @@ void ParseInit (type* T)
|
|||||||
}
|
}
|
||||||
ConsumeRCurly ();
|
ConsumeRCurly ();
|
||||||
}
|
}
|
||||||
if (Size == 0) {
|
if (ElementCount == UNSPECIFIED) {
|
||||||
Encode (T + 1, Count);
|
Encode (T + 1, Count);
|
||||||
} else if (Count < Size) {
|
} else if (Count < ElementCount) {
|
||||||
g_zerobytes ((Size - Count) * CheckedSizeOf (T + DECODE_SIZE + 1));
|
g_zerobytes ((ElementCount - Count) * ElementSize);
|
||||||
} else if (Count > Size) {
|
} else if (Count > ElementCount) {
|
||||||
Error ("Too many initializers");
|
Error ("Too many initializers");
|
||||||
}
|
}
|
||||||
break;
|
return ElementCount * ElementSize;
|
||||||
|
|
||||||
case T_STRUCT:
|
case T_STRUCT:
|
||||||
case T_UNION:
|
case T_UNION:
|
||||||
ParseStructInit (T);
|
return ParseStructInit (T);
|
||||||
break;
|
|
||||||
|
|
||||||
case T_VOID:
|
case T_VOID:
|
||||||
if (!ANSI) {
|
if (!ANSI) {
|
||||||
/* Special cc65 extension in non ANSI mode */
|
/* Special cc65 extension in non ANSI mode */
|
||||||
ParseVoidInit ();
|
return ParseVoidInit ();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Error ("Illegal type");
|
Error ("Illegal type");
|
||||||
break;
|
return SIZEOF_CHAR;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2001 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@ -101,8 +101,10 @@ void CheckEmptyDecl (const DeclSpec* D);
|
|||||||
* warning if not.
|
* warning if not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ParseInit (type* T);
|
unsigned ParseInit (type* T);
|
||||||
/* Parse initialization of variables. */
|
/* Parse initialization of variables. Return the number of initialized data
|
||||||
|
* bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2001 Ullrich von Bassewitz */
|
/* (C) 2000-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
@ -717,17 +717,17 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
|
|||||||
if (IsTypeArray (Type) && IsTypeArray (EType)) {
|
if (IsTypeArray (Type) && IsTypeArray (EType)) {
|
||||||
|
|
||||||
/* Get the array sizes */
|
/* Get the array sizes */
|
||||||
unsigned Size = Decode (Type + 1);
|
long Size = GetElementCount (Type);
|
||||||
unsigned ESize = Decode (EType + 1);
|
long ESize = GetElementCount (EType);
|
||||||
|
|
||||||
if ((Size != 0 && ESize != 0 && Size != ESize) ||
|
if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
|
||||||
TypeCmp (Type+DECODE_SIZE+1, EType+DECODE_SIZE+1) < TC_EQUAL) {
|
TypeCmp (Type+DECODE_SIZE+1, EType+DECODE_SIZE+1) < TC_EQUAL) {
|
||||||
/* Types not identical: Conflicting types */
|
/* Types not identical: Conflicting types */
|
||||||
Error ("Conflicting types for `%s'", Name);
|
Error ("Conflicting types for `%s'", Name);
|
||||||
return Entry;
|
return Entry;
|
||||||
} else {
|
} else {
|
||||||
/* Check if we have a size in the existing definition */
|
/* Check if we have a size in the existing definition */
|
||||||
if (ESize == 0) {
|
if (ESize == UNSPECIFIED) {
|
||||||
/* Existing, size not given, use size from new def */
|
/* Existing, size not given, use size from new def */
|
||||||
Encode (EType + 1, Size);
|
Encode (EType + 1, Size);
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@ -149,7 +149,7 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
|||||||
type LeftType, RightType;
|
type LeftType, RightType;
|
||||||
type LeftSign, RightSign;
|
type LeftSign, RightSign;
|
||||||
type LeftQual, RightQual;
|
type LeftQual, RightQual;
|
||||||
unsigned LeftCount, RightCount;
|
long LeftCount, RightCount;
|
||||||
|
|
||||||
/* Check if the end of the type string is reached */
|
/* Check if the end of the type string is reached */
|
||||||
if (*rhs == T_END) {
|
if (*rhs == T_END) {
|
||||||
@ -274,9 +274,11 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
|||||||
|
|
||||||
case T_TYPE_ARRAY:
|
case T_TYPE_ARRAY:
|
||||||
/* Check member count */
|
/* Check member count */
|
||||||
LeftCount = Decode (lhs+1);
|
LeftCount = GetElementCount (lhs);
|
||||||
RightCount = Decode (rhs+1);
|
RightCount = GetElementCount (rhs);
|
||||||
if (LeftCount != 0 && RightCount != 0 && LeftCount != RightCount) {
|
if (LeftCount != UNSPECIFIED &&
|
||||||
|
RightCount != UNSPECIFIED &&
|
||||||
|
LeftCount != RightCount) {
|
||||||
/* Member count given but different */
|
/* Member count given but different */
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
SetResult (Result, TC_INCOMPATIBLE);
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user