Removed the non-existing-in-C "struct/union scope" for structs/unions.

Fixed handling of struct/union field declarations without identifiers, which do nothing.
This commit is contained in:
acqn 2021-03-29 12:35:29 +08:00 committed by Oliver Schmidt
parent edecbc86b8
commit cb8fbf4772
5 changed files with 62 additions and 36 deletions

View File

@ -965,7 +965,7 @@ static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags)
*/
AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth,
SignednessSpecified);
} else {
} else if (Decl.Ident[0] != '\0') {
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
if (IsAnonName (Decl.Ident)) {
Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++;
@ -994,7 +994,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
NextToken ();
/* Remember the symbol table and leave the struct level */
FieldTab = GetSymTab ();
FieldTab = GetFieldSymTab ();
LeaveStructLevel ();
/* Return a fictitious symbol if errors occurred during parsing */
@ -1167,7 +1167,7 @@ static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags)
/* Add any full bytes to the struct size. */
StructSize += BitOffs / CHAR_BITS;
BitOffs %= CHAR_BITS;
} else {
} else if (Decl.Ident[0] != '\0') {
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
if (IsAnonName (Decl.Ident)) {
Entry->V.A.ANumber = StructTagEntry->V.S.ACount++;
@ -1208,7 +1208,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
NextToken ();
/* Remember the symbol table and leave the struct level */
FieldTab = GetSymTab ();
FieldTab = GetFieldSymTab ();
LeaveStructLevel ();
/* Return a fictitious symbol if errors occurred during parsing */

View File

@ -92,6 +92,7 @@ static SymTable* SymTab0 = 0;
static SymTable* SymTab = 0;
static SymTable* TagTab0 = 0;
static SymTable* TagTab = 0;
static SymTable* FieldTab = 0;
static SymTable* LabelTab = 0;
static SymTable* SPAdjustTab = 0;
static SymTable* FailSafeTab = 0; /* For errors */
@ -390,9 +391,9 @@ void EnterStructLevel (void)
** nested in struct scope are NOT local to the struct but visible in the
** outside scope. So we will NOT create a new struct or enum table.
*/
S = NewSymTable (SYMTAB_SIZE_BLOCK);
S->PrevTab = SymTab;
SymTab = S;
S = NewSymTable (SYMTAB_SIZE_STRUCT);
S->PrevTab = FieldTab;
FieldTab = S;
}
@ -401,7 +402,7 @@ void LeaveStructLevel (void)
/* Leave a nested block for a struct definition */
{
/* Don't delete the table */
SymTab = SymTab->PrevTab;
FieldTab = FieldTab->PrevTab;
}
@ -850,7 +851,7 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs,
/* Add a bit field to the local symbol table and return the symbol entry */
{
/* Do we have an entry with this name already? */
SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));
SymEntry* Entry = FindSymInTable (FieldTab, Name, HashStr (Name));
if (Entry) {
/* We have a symbol with this name already */
@ -882,7 +883,7 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs,
}
/* Add the entry to the symbol table */
AddSymEntry (SymTab, Entry);
AddSymEntry (FieldTab, Entry);
}
@ -1070,9 +1071,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs)
/* Add a local symbol and return the symbol entry */
/* Add a local or struct/union field symbol and return the symbol entry */
{
SymTable* Tab = SymTab;
SymTable* Tab = (Flags & SC_STRUCTFIELD) == 0 ? SymTab : FieldTab;
ident Ident;
/* Do we have an entry with this name already? */
@ -1267,6 +1268,16 @@ SymTable* GetGlobalSymTab (void)
return SymTab0;
}
SymTable* GetFieldSymTab (void)
/* Return the current field symbol table */
{
return FieldTab;
}
SymTable* GetLabelSymTab (void)
/* Return the global symbol table */
{

View File

@ -166,7 +166,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags);
/* Add a goto label to the symbol table */
SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs);
/* Add a local symbol and return the symbol entry */
/* Add a local or struct/union field symbol and return the symbol entry */
SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags);
/* Add an external or global symbol to the symbol table and return the entry */
@ -185,6 +185,9 @@ SymTable* GetSymTab (void);
SymTable* GetGlobalSymTab (void);
/* Return the global symbol table */
SymTable* GetFieldSymTab (void);
/* Return the current field symbol table */
SymTable* GetLabelSymTab (void);
/* Return the label symbol table */

View File

@ -1,23 +0,0 @@
/* bug #1437 enum declaration in struct does not compile */
struct nodelist1 {
enum { DEAD1, LIVE1, ONCE1, TWICE1 } live1;
} firstnode1 = {ONCE1};
enum nodestate2 { DEAD2, LIVE2, ONCE2, TWICE2 } live2;
struct nodelist2 {
enum nodestate2 live2;
} firstnode2 = {TWICE2};
int main (void)
{
if (firstnode1.live1 != ONCE1) {
return 1;
}
if (firstnode2.live2 != TWICE2) {
return 1;
}
return 0;
}

35
test/val/bug1437.c Normal file
View File

@ -0,0 +1,35 @@
/* bug #1437 enum declaration in a struct/union is invisible in the scope where the struct/union is declared */
struct nodelist1 {
struct {
enum { DEAD1, LIVE1, ONCE1, TWICE1 } live1;
} s;
} firstnode1 = {ONCE1};
enum nodestate2 { DEAD2, LIVE2, ONCE2, TWICE2 } live2;
union nodelist2 {
enum nodestate2 live2;
} firstnode2 = { {TWICE2} };
struct T {
int I;
int;
enum E {
I
};
};
int failures = 0;
int main (void)
{
if (firstnode1.s.live1 != ONCE1) {
++failures;
}
if (firstnode2.live2 != TWICE2) {
++failures;
}
return failures;
}