1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-11 11:30:13 +00:00

Improved ESU declaration failure handling.

This commit is contained in:
acqn 2020-08-12 21:33:46 +08:00 committed by Oliver Schmidt
parent dc83eb15af
commit 8a417ff039
3 changed files with 70 additions and 32 deletions

View File

@ -479,7 +479,7 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
static SymEntry* ESUForwardDecl (const char* Name, unsigned Type) static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags)
/* Handle an enum, struct or union forward decl */ /* Handle an enum, struct or union forward decl */
{ {
/* Try to find an enum/struct/union with the given name. If there is none, /* Try to find an enum/struct/union with the given name. If there is none,
@ -487,12 +487,12 @@ static SymEntry* ESUForwardDecl (const char* Name, unsigned Type)
*/ */
SymEntry* Entry = FindTagSym (Name); SymEntry* Entry = FindTagSym (Name);
if (Entry == 0) { if (Entry == 0) {
if (Type != SC_ENUM) { if ((Flags & SC_ESUTYPEMASK) != SC_ENUM) {
Entry = AddStructSym (Name, Type, 0, 0); Entry = AddStructSym (Name, Flags, 0, 0);
} else { } else {
Entry = AddEnumSym (Name, 0, 0); Entry = AddEnumSym (Name, Flags, 0, 0);
} }
} else if ((Entry->Flags & SC_TYPEMASK) != Type) { } else if ((Entry->Flags & SC_TYPEMASK) != (Flags & SC_ESUTYPEMASK)) {
/* Already defined, but not the same type class */ /* Already defined, but not the same type class */
Error ("Symbol '%s' is already different kind", Name); Error ("Symbol '%s' is already different kind", Name);
} }
@ -551,14 +551,17 @@ static SymEntry* ParseEnumDecl (const char* Name)
unsigned long MaxConstant = 0; unsigned long MaxConstant = 0;
const Type* NewType = 0; /* new member type */ const Type* NewType = 0; /* new member type */
const Type* MemberType = type_int; /* default member type */ const Type* MemberType = type_int; /* default member type */
unsigned Flags = 0;
unsigned PrevErrorCount = ErrorCount;
/* Accept forward definitions */
if (CurTok.Tok != TOK_LCURLY) { if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward definition */
return ESUForwardDecl (Name, SC_ENUM); return ESUForwardDecl (Name, SC_ENUM);
} }
/* Add the enum tag */ /* Add a forward declaration for the enum tag in the current lexical level */
AddEnumSym (Name, 0, 0); AddEnumSym (Name, 0, 0, 0);
/* Skip the opening curly brace */ /* Skip the opening curly brace */
NextToken (); NextToken ();
@ -695,7 +698,13 @@ static SymEntry* ParseEnumDecl (const char* Name)
} }
FieldTab = GetSymTab (); FieldTab = GetSymTab ();
return AddEnumSym (Name, MemberType, FieldTab);
/* Return a fictitious symbol if errors occurred during parsing */
if (PrevErrorCount != ErrorCount) {
Flags |= SC_FICTITIOUS;
}
return AddEnumSym (Name, Flags, MemberType, FieldTab);
} }
@ -829,19 +838,21 @@ static SymEntry* ParseUnionDecl (const char* Name)
unsigned FieldSize; unsigned FieldSize;
int FieldWidth; /* Width in bits, -1 if not a bit-field */ int FieldWidth; /* Width in bits, -1 if not a bit-field */
SymTable* FieldTab; SymTable* FieldTab;
SymEntry* StructTypeEntry; SymEntry* UnionTagEntry;
SymEntry* Entry; SymEntry* Entry;
unsigned Flags = 0;
unsigned PrevErrorCount = ErrorCount;
if (CurTok.Tok != TOK_LCURLY) { if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward declaration. */ /* Just a forward declaration */
return ESUForwardDecl (Name, SC_UNION); return ESUForwardDecl (Name, SC_UNION);
} }
/* Add a forward declaration for the struct in the current lexical level */ /* Add a forward declaration for the union tag in the current lexical level */
StructTypeEntry = AddStructSym (Name, SC_UNION, 0, 0); UnionTagEntry = AddStructSym (Name, SC_UNION, 0, 0);
StructTypeEntry->V.S.ACount = 0; UnionTagEntry->V.S.ACount = 0;
/* Skip the curly brace */ /* Skip the curly brace */
NextToken (); NextToken ();
@ -883,7 +894,7 @@ static SymEntry* ParseUnionDecl (const char* Name)
/* This is an anonymous struct or union. Copy the fields /* This is an anonymous struct or union. Copy the fields
** into the current level. ** into the current level.
*/ */
AnonFieldName (Decl.Ident, "field", StructTypeEntry->V.S.ACount); AnonFieldName (Decl.Ident, "field", UnionTagEntry->V.S.ACount);
} else { } else {
/* A non bit-field without a name is legal but useless */ /* A non bit-field without a name is legal but useless */
Warning ("Declaration does not declare anything"); Warning ("Declaration does not declare anything");
@ -902,7 +913,7 @@ static SymEntry* ParseUnionDecl (const char* Name)
} else { } else {
if (IsAnonName (Decl.Ident)) { if (IsAnonName (Decl.Ident)) {
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
Entry->V.A.ANumber = StructTypeEntry->V.S.ACount++; Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++;
AliasAnonStructFields (&Decl, Entry); AliasAnonStructFields (&Decl, Entry);
} else { } else {
AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
@ -929,8 +940,13 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
Error ("Empty union type '%s' is not supported", Name); Error ("Empty union type '%s' is not supported", Name);
} }
/* Return a fictitious symbol if errors occurred during parsing */
if (PrevErrorCount != ErrorCount) {
Flags |= SC_FICTITIOUS;
}
/* Make a real entry from the forward decl and return it */ /* Make a real entry from the forward decl and return it */
return AddStructSym (Name, SC_UNION | SC_DEF, UnionSize, FieldTab); return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab);
} }
@ -944,19 +960,21 @@ static SymEntry* ParseStructDecl (const char* Name)
unsigned BitOffs; /* Bit offset for bit-fields */ unsigned BitOffs; /* Bit offset for bit-fields */
int FieldWidth; /* Width in bits, -1 if not a bit-field */ int FieldWidth; /* Width in bits, -1 if not a bit-field */
SymTable* FieldTab; SymTable* FieldTab;
SymEntry* StructTypeEntry; SymEntry* StructTagEntry;
SymEntry* Entry; SymEntry* Entry;
unsigned Flags = 0;
unsigned PrevErrorCount = ErrorCount;
if (CurTok.Tok != TOK_LCURLY) { if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward declaration. */ /* Just a forward declaration */
return ESUForwardDecl (Name, SC_STRUCT); return ESUForwardDecl (Name, SC_STRUCT);
} }
/* Add a forward declaration for the struct in the current lexical level */ /* Add a forward declaration for the struct tag in the current lexical level */
StructTypeEntry = AddStructSym (Name, SC_STRUCT, 0, 0); StructTagEntry = AddStructSym (Name, SC_STRUCT, 0, 0);
StructTypeEntry->V.S.ACount = 0; StructTagEntry->V.S.ACount = 0;
/* Skip the curly brace */ /* Skip the curly brace */
NextToken (); NextToken ();
@ -1050,7 +1068,7 @@ static SymEntry* ParseStructDecl (const char* Name)
/* This is an anonymous struct or union. Copy the /* This is an anonymous struct or union. Copy the
** fields into the current level. ** fields into the current level.
*/ */
AnonFieldName (Decl.Ident, "field", StructTypeEntry->V.S.ACount); AnonFieldName (Decl.Ident, "field", StructTagEntry->V.S.ACount);
} else { } else {
/* A non bit-field without a name is legal but useless */ /* A non bit-field without a name is legal but useless */
Warning ("Declaration does not declare anything"); Warning ("Declaration does not declare anything");
@ -1078,7 +1096,7 @@ static SymEntry* ParseStructDecl (const char* Name)
} else { } else {
if (IsAnonName (Decl.Ident)) { if (IsAnonName (Decl.Ident)) {
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
Entry->V.A.ANumber = StructTypeEntry->V.S.ACount++; Entry->V.A.ANumber = StructTagEntry->V.S.ACount++;
AliasAnonStructFields (&Decl, Entry); AliasAnonStructFields (&Decl, Entry);
} else { } else {
AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
@ -1116,8 +1134,13 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
Error ("Empty struct type '%s' is not supported", Name); Error ("Empty struct type '%s' is not supported", Name);
} }
/* Return a fictitious symbol if errors occurred during parsing */
if (PrevErrorCount != ErrorCount) {
Flags |= SC_FICTITIOUS;
}
/* Make a real entry from the forward decl and return it */ /* Make a real entry from the forward decl and return it */
return AddStructSym (Name, SC_STRUCT | SC_DEF, StructSize, FieldTab); return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab);
} }

View File

@ -682,13 +682,21 @@ static void AddSymEntry (SymTable* T, SymEntry* S)
SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab)
/* Add an enum entry and return it */ /* Add an enum entry and return it */
{ {
SymTable* CurTagTab = TagTab; SymTable* CurTagTab = TagTab;
SymEntry* Entry;
if ((Flags & SC_FICTITIOUS) == 0) {
/* Do we have an entry with this name already? */
Entry = FindSymInTable (CurTagTab, Name, HashStr (Name));
} else {
/* Add a fictitious symbol in the fail-safe table */
Entry = 0;
CurTagTab = FailSafeTab;
}
/* Do we have an entry with this name already? */
SymEntry* Entry = FindSymInTable (CurTagTab, Name, HashStr (Name));
if (Entry) { if (Entry) {
/* We do have an entry. This may be a forward, so check it. */ /* We do have an entry. This may be a forward, so check it. */
@ -749,8 +757,15 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl
/* Type must be struct or union */ /* Type must be struct or union */
PRECONDITION (Type == SC_STRUCT || Type == SC_UNION); PRECONDITION (Type == SC_STRUCT || Type == SC_UNION);
/* Do we have an entry with this name already? */ if ((Flags & SC_FICTITIOUS) == 0) {
Entry = FindSymInTable (CurTagTab, Name, HashStr (Name)); /* Do we have an entry with this name already? */
Entry = FindSymInTable (CurTagTab, Name, HashStr (Name));
} else {
/* Add a fictitious symbol in the fail-safe table */
Entry = 0;
CurTagTab = FailSafeTab;
}
if (Entry) { if (Entry) {
/* We do have an entry. This may be a forward, so check it. */ /* We do have an entry. This may be a forward, so check it. */

View File

@ -149,10 +149,10 @@ unsigned short FindSPAdjustment (const char* Name);
SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab); SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab);
/* Add an enum entry and return it */ /* Add an enum entry and return it */
SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable* Tab); SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab);
/* Add a struct/union entry and return it */ /* Add a struct/union entry and return it */
SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned BitWidth); SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned BitWidth);