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:
parent
edecbc86b8
commit
cb8fbf4772
5 changed files with 62 additions and 36 deletions
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
35
test/val/bug1437.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue