1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 23:29:39 +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 */
{
/* 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);
if (Entry == 0) {
if (Type != SC_ENUM) {
Entry = AddStructSym (Name, Type, 0, 0);
if ((Flags & SC_ESUTYPEMASK) != SC_ENUM) {
Entry = AddStructSym (Name, Flags, 0, 0);
} 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 */
Error ("Symbol '%s' is already different kind", Name);
}
@ -551,14 +551,17 @@ static SymEntry* ParseEnumDecl (const char* Name)
unsigned long MaxConstant = 0;
const Type* NewType = 0; /* new member type */
const Type* MemberType = type_int; /* default member type */
unsigned Flags = 0;
unsigned PrevErrorCount = ErrorCount;
/* Accept forward definitions */
if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward definition */
return ESUForwardDecl (Name, SC_ENUM);
}
/* Add the enum tag */
AddEnumSym (Name, 0, 0);
/* Add a forward declaration for the enum tag in the current lexical level */
AddEnumSym (Name, 0, 0, 0);
/* Skip the opening curly brace */
NextToken ();
@ -695,7 +698,13 @@ static SymEntry* ParseEnumDecl (const char* Name)
}
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;
int FieldWidth; /* Width in bits, -1 if not a bit-field */
SymTable* FieldTab;
SymEntry* StructTypeEntry;
SymEntry* UnionTagEntry;
SymEntry* Entry;
unsigned Flags = 0;
unsigned PrevErrorCount = ErrorCount;
if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward declaration. */
/* Just a forward declaration */
return ESUForwardDecl (Name, SC_UNION);
}
/* Add a forward declaration for the struct in the current lexical level */
StructTypeEntry = AddStructSym (Name, SC_UNION, 0, 0);
/* Add a forward declaration for the union tag in the current lexical level */
UnionTagEntry = AddStructSym (Name, SC_UNION, 0, 0);
StructTypeEntry->V.S.ACount = 0;
UnionTagEntry->V.S.ACount = 0;
/* Skip the curly brace */
NextToken ();
@ -883,7 +894,7 @@ static SymEntry* ParseUnionDecl (const char* Name)
/* This is an anonymous struct or union. Copy the fields
** into the current level.
*/
AnonFieldName (Decl.Ident, "field", StructTypeEntry->V.S.ACount);
AnonFieldName (Decl.Ident, "field", UnionTagEntry->V.S.ACount);
} else {
/* A non bit-field without a name is legal but useless */
Warning ("Declaration does not declare anything");
@ -902,7 +913,7 @@ static SymEntry* ParseUnionDecl (const char* Name)
} else {
if (IsAnonName (Decl.Ident)) {
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);
} else {
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);
}
/* 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 */
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 */
int FieldWidth; /* Width in bits, -1 if not a bit-field */
SymTable* FieldTab;
SymEntry* StructTypeEntry;
SymEntry* StructTagEntry;
SymEntry* Entry;
unsigned Flags = 0;
unsigned PrevErrorCount = ErrorCount;
if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward declaration. */
/* Just a forward declaration */
return ESUForwardDecl (Name, SC_STRUCT);
}
/* Add a forward declaration for the struct in the current lexical level */
StructTypeEntry = AddStructSym (Name, SC_STRUCT, 0, 0);
/* Add a forward declaration for the struct tag in the current lexical level */
StructTagEntry = AddStructSym (Name, SC_STRUCT, 0, 0);
StructTypeEntry->V.S.ACount = 0;
StructTagEntry->V.S.ACount = 0;
/* Skip the curly brace */
NextToken ();
@ -1050,7 +1068,7 @@ static SymEntry* ParseStructDecl (const char* Name)
/* This is an anonymous struct or union. Copy the
** fields into the current level.
*/
AnonFieldName (Decl.Ident, "field", StructTypeEntry->V.S.ACount);
AnonFieldName (Decl.Ident, "field", StructTagEntry->V.S.ACount);
} else {
/* A non bit-field without a name is legal but useless */
Warning ("Declaration does not declare anything");
@ -1078,7 +1096,7 @@ static SymEntry* ParseStructDecl (const char* Name)
} else {
if (IsAnonName (Decl.Ident)) {
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);
} else {
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);
}
/* 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 */
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 */
{
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) {
/* 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 */
PRECONDITION (Type == SC_STRUCT || Type == SC_UNION);
/* Do we have an entry with this name already? */
Entry = FindSymInTable (CurTagTab, Name, HashStr (Name));
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;
}
if (Entry) {
/* 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 */
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 */
SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned BitWidth);