mirror of
https://github.com/cc65/cc65.git
synced 2025-01-12 02:30:44 +00:00
Implement anonymous structs/unions in cc65 mode.
git-svn-id: svn://svn.cc65.org/cc65/trunk@5618 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
9f2d63a3ae
commit
63328d3852
@ -545,6 +545,52 @@ static SymEntry* StructOrUnionForwardDecl (const char* Name)
|
||||
|
||||
|
||||
|
||||
static unsigned CopyAnonStructFields (const Declaration* Decl, int Offs)
|
||||
/* Copy fields from an anon union/struct into the current lexical level. The
|
||||
* function returns the size of the embedded struct/union.
|
||||
*/
|
||||
{
|
||||
/* Get the pointer to the symbol table entry of the anon struct */
|
||||
SymEntry* Entry = GetSymEntry (Decl->Type);
|
||||
|
||||
/* Get the size of the anon struct */
|
||||
unsigned Size = Entry->V.S.Size;
|
||||
|
||||
/* Get the symbol table containing the fields. If it is empty, there has
|
||||
* been an error before, so bail out.
|
||||
*/
|
||||
SymTable* Tab = Entry->V.S.SymTab;
|
||||
if (Tab == 0) {
|
||||
/* Incomplete definition - has been flagged before */
|
||||
return Size;
|
||||
}
|
||||
|
||||
/* Get a pointer to the list of symbols. Then walk the list adding copies
|
||||
* of the embedded struct to the current level.
|
||||
*/
|
||||
Entry = Tab->SymHead;
|
||||
while (Entry) {
|
||||
|
||||
/* Enter a copy of this symbol adjusting the offset. We will just
|
||||
* reuse the type string here.
|
||||
*/
|
||||
AddLocalSym (Entry->Name, Entry->Type,SC_STRUCTFIELD, Offs + Entry->V.Offs);
|
||||
|
||||
/* Currently, there can not be any attributes, but if there will be
|
||||
* some in the future, we want to know this.
|
||||
*/
|
||||
CHECK (Entry->Attr == 0);
|
||||
|
||||
/* Next entry */
|
||||
Entry = Entry->NextSym;
|
||||
}
|
||||
|
||||
/* Return the size of the embedded struct */
|
||||
return Size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static SymEntry* ParseUnionDecl (const char* Name)
|
||||
/* Parse a union declaration. */
|
||||
{
|
||||
@ -597,8 +643,19 @@ static SymEntry* ParseUnionDecl (const char* Name)
|
||||
|
||||
/* Check for fields without a name */
|
||||
if (Decl.Ident[0] == '\0') {
|
||||
/* Any field without a name is legal but useless in a union */
|
||||
Warning ("Declaration does not declare anything");
|
||||
/* In cc65 mode, we allow anonymous structs/unions within
|
||||
* a struct.
|
||||
*/
|
||||
if (IS_Get (&Standard) >= STD_CC65 && IsClassStruct (Decl.Type)) {
|
||||
/* This is an anonymous struct or union. Copy the fields
|
||||
* into the current level.
|
||||
*/
|
||||
CopyAnonStructFields (&Decl, 0);
|
||||
|
||||
} else {
|
||||
/* A non bit-field without a name is legal but useless */
|
||||
Warning ("Declaration does not declare anything");
|
||||
}
|
||||
goto NextMember;
|
||||
}
|
||||
|
||||
@ -722,18 +779,6 @@ static SymEntry* ParseStructDecl (const char* Name)
|
||||
goto NextMember;
|
||||
}
|
||||
|
||||
/* Check for fields without names */
|
||||
if (Decl.Ident[0] == '\0') {
|
||||
if (FieldWidth < 0) {
|
||||
/* A non bit-field without a name is legal but useless */
|
||||
Warning ("Declaration does not declare anything");
|
||||
goto NextMember;
|
||||
} else {
|
||||
/* A bit-field without a name will get an anonymous one */
|
||||
AnonName (Decl.Ident, "bit-field");
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if this field is a flexible array member, and
|
||||
* calculate the size of the field.
|
||||
*/
|
||||
@ -747,6 +792,30 @@ static SymEntry* ParseStructDecl (const char* Name)
|
||||
SetElementCount (Decl.Type, FLEXIBLE);
|
||||
}
|
||||
|
||||
/* Check for fields without names */
|
||||
if (Decl.Ident[0] == '\0') {
|
||||
if (FieldWidth < 0) {
|
||||
/* In cc65 mode, we allow anonymous structs/unions within
|
||||
* a struct.
|
||||
*/
|
||||
if (IS_Get (&Standard) >= STD_CC65 && IsClassStruct (Decl.Type)) {
|
||||
|
||||
/* This is an anonymous struct or union. Copy the
|
||||
* fields into the current level.
|
||||
*/
|
||||
StructSize += CopyAnonStructFields (&Decl, StructSize);
|
||||
|
||||
} else {
|
||||
/* A non bit-field without a name is legal but useless */
|
||||
Warning ("Declaration does not declare anything");
|
||||
}
|
||||
goto NextMember;
|
||||
} else {
|
||||
/* A bit-field without a name will get an anonymous one */
|
||||
AnonName (Decl.Ident, "bit-field");
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a field entry to the table */
|
||||
if (FieldWidth > 0) {
|
||||
/* Add full byte from the bit offset to the variable offset.
|
||||
|
Loading…
x
Reference in New Issue
Block a user