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,
|
AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth,
|
||||||
SignednessSpecified);
|
SignednessSpecified);
|
||||||
} else {
|
} else if (Decl.Ident[0] != '\0') {
|
||||||
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
|
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
|
||||||
if (IsAnonName (Decl.Ident)) {
|
if (IsAnonName (Decl.Ident)) {
|
||||||
Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++;
|
Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++;
|
||||||
|
@ -994,7 +994,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Remember the symbol table and leave the struct level */
|
/* Remember the symbol table and leave the struct level */
|
||||||
FieldTab = GetSymTab ();
|
FieldTab = GetFieldSymTab ();
|
||||||
LeaveStructLevel ();
|
LeaveStructLevel ();
|
||||||
|
|
||||||
/* Return a fictitious symbol if errors occurred during parsing */
|
/* 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. */
|
/* Add any full bytes to the struct size. */
|
||||||
StructSize += BitOffs / CHAR_BITS;
|
StructSize += BitOffs / CHAR_BITS;
|
||||||
BitOffs %= CHAR_BITS;
|
BitOffs %= CHAR_BITS;
|
||||||
} else {
|
} else if (Decl.Ident[0] != '\0') {
|
||||||
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
|
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
|
||||||
if (IsAnonName (Decl.Ident)) {
|
if (IsAnonName (Decl.Ident)) {
|
||||||
Entry->V.A.ANumber = StructTagEntry->V.S.ACount++;
|
Entry->V.A.ANumber = StructTagEntry->V.S.ACount++;
|
||||||
|
@ -1208,7 +1208,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Remember the symbol table and leave the struct level */
|
/* Remember the symbol table and leave the struct level */
|
||||||
FieldTab = GetSymTab ();
|
FieldTab = GetFieldSymTab ();
|
||||||
LeaveStructLevel ();
|
LeaveStructLevel ();
|
||||||
|
|
||||||
/* Return a fictitious symbol if errors occurred during parsing */
|
/* Return a fictitious symbol if errors occurred during parsing */
|
||||||
|
|
|
@ -92,6 +92,7 @@ static SymTable* SymTab0 = 0;
|
||||||
static SymTable* SymTab = 0;
|
static SymTable* SymTab = 0;
|
||||||
static SymTable* TagTab0 = 0;
|
static SymTable* TagTab0 = 0;
|
||||||
static SymTable* TagTab = 0;
|
static SymTable* TagTab = 0;
|
||||||
|
static SymTable* FieldTab = 0;
|
||||||
static SymTable* LabelTab = 0;
|
static SymTable* LabelTab = 0;
|
||||||
static SymTable* SPAdjustTab = 0;
|
static SymTable* SPAdjustTab = 0;
|
||||||
static SymTable* FailSafeTab = 0; /* For errors */
|
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
|
** 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.
|
** outside scope. So we will NOT create a new struct or enum table.
|
||||||
*/
|
*/
|
||||||
S = NewSymTable (SYMTAB_SIZE_BLOCK);
|
S = NewSymTable (SYMTAB_SIZE_STRUCT);
|
||||||
S->PrevTab = SymTab;
|
S->PrevTab = FieldTab;
|
||||||
SymTab = S;
|
FieldTab = S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -401,7 +402,7 @@ void LeaveStructLevel (void)
|
||||||
/* Leave a nested block for a struct definition */
|
/* Leave a nested block for a struct definition */
|
||||||
{
|
{
|
||||||
/* Don't delete the table */
|
/* 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 */
|
/* Add a bit field to the local symbol table and return the symbol entry */
|
||||||
{
|
{
|
||||||
/* Do we have an entry with this name already? */
|
/* 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) {
|
if (Entry) {
|
||||||
|
|
||||||
/* We have a symbol with this name already */
|
/* 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 */
|
/* 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)
|
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;
|
ident Ident;
|
||||||
|
|
||||||
/* Do we have an entry with this name already? */
|
/* Do we have an entry with this name already? */
|
||||||
|
@ -1267,6 +1268,16 @@ SymTable* GetGlobalSymTab (void)
|
||||||
return SymTab0;
|
return SymTab0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SymTable* GetFieldSymTab (void)
|
||||||
|
/* Return the current field symbol table */
|
||||||
|
{
|
||||||
|
return FieldTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymTable* GetLabelSymTab (void)
|
SymTable* GetLabelSymTab (void)
|
||||||
/* Return the global symbol table */
|
/* Return the global symbol table */
|
||||||
{
|
{
|
||||||
|
|
|
@ -166,7 +166,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags);
|
||||||
/* Add a goto label to the symbol table */
|
/* Add a goto label to the symbol table */
|
||||||
|
|
||||||
SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs);
|
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);
|
SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags);
|
||||||
/* Add an external or global symbol to the symbol table and return the entry */
|
/* Add an external or global symbol to the symbol table and return the entry */
|
||||||
|
@ -185,6 +185,9 @@ SymTable* GetSymTab (void);
|
||||||
SymTable* GetGlobalSymTab (void);
|
SymTable* GetGlobalSymTab (void);
|
||||||
/* Return the global symbol table */
|
/* Return the global symbol table */
|
||||||
|
|
||||||
|
SymTable* GetFieldSymTab (void);
|
||||||
|
/* Return the current field symbol table */
|
||||||
|
|
||||||
SymTable* GetLabelSymTab (void);
|
SymTable* GetLabelSymTab (void);
|
||||||
/* Return the label symbol table */
|
/* 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