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:
parent
dc83eb15af
commit
8a417ff039
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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. */
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user