mirror of
https://github.com/cc65/cc65.git
synced 2024-09-29 02:55:20 +00:00
More accurate diagnostic messages on wrong missing declaration specifiers.
This commit is contained in:
parent
cadf8012f6
commit
3215d377ea
@ -88,6 +88,7 @@ static void Parse (void)
|
|||||||
/* Fill up the next token with a bogus semicolon and start the tokenizer */
|
/* Fill up the next token with a bogus semicolon and start the tokenizer */
|
||||||
NextTok.Tok = TOK_SEMI;
|
NextTok.Tok = TOK_SEMI;
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
NextToken ();
|
||||||
|
|
||||||
/* Parse until end of input */
|
/* Parse until end of input */
|
||||||
while (CurTok.Tok != TOK_CEOF) {
|
while (CurTok.Tok != TOK_CEOF) {
|
||||||
@ -98,6 +99,7 @@ static void Parse (void)
|
|||||||
|
|
||||||
/* Check for empty statements */
|
/* Check for empty statements */
|
||||||
if (CurTok.Tok == TOK_SEMI) {
|
if (CurTok.Tok == TOK_SEMI) {
|
||||||
|
/* TODO: warn on this if we have a pedantic mode */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -137,6 +139,16 @@ static void Parse (void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we haven't got a type specifier yet, something must be wrong */
|
||||||
|
if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) {
|
||||||
|
/* Avoid extra errors if it was a failed type specifier */
|
||||||
|
if ((Spec.Flags & DS_EXTRA_TYPE) == 0) {
|
||||||
|
Error ("Declaration specifier expected");
|
||||||
|
}
|
||||||
|
NeedClean = -1;
|
||||||
|
goto EndOfDecl;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read declarations for this type */
|
/* Read declarations for this type */
|
||||||
Comma = 0;
|
Comma = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -355,6 +367,7 @@ static void Parse (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EndOfDecl:
|
||||||
/* Try some smart error recovery */
|
/* Try some smart error recovery */
|
||||||
if (NeedClean < 0) {
|
if (NeedClean < 0) {
|
||||||
SmartErrorSkip (1);
|
SmartErrorSkip (1);
|
||||||
|
@ -979,6 +979,13 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags)
|
|||||||
DeclSpec Spec;
|
DeclSpec Spec;
|
||||||
int NeedClean = 0;
|
int NeedClean = 0;
|
||||||
|
|
||||||
|
/* Check for extra semicolons */
|
||||||
|
if (CurTok.Tok == TOK_SEMI) {
|
||||||
|
/* TODO: warn on this if we have a pedantic mode */
|
||||||
|
NextToken ();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for a _Static_assert */
|
/* Check for a _Static_assert */
|
||||||
if (CurTok.Tok == TOK_STATIC_ASSERT) {
|
if (CurTok.Tok == TOK_STATIC_ASSERT) {
|
||||||
ParseStaticAssert ();
|
ParseStaticAssert ();
|
||||||
@ -995,6 +1002,16 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we haven't got a type specifier yet, something must be wrong */
|
||||||
|
if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) {
|
||||||
|
/* Avoid extra errors if it was a failed type specifier */
|
||||||
|
if ((Spec.Flags & DS_EXTRA_TYPE) == 0) {
|
||||||
|
Error ("Declaration specifier expected");
|
||||||
|
}
|
||||||
|
NeedClean = -1;
|
||||||
|
goto EndOfDecl;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allow anonymous bit-fields */
|
/* Allow anonymous bit-fields */
|
||||||
Spec.Flags |= DS_ALLOW_BITFIELD;
|
Spec.Flags |= DS_ALLOW_BITFIELD;
|
||||||
|
|
||||||
@ -1107,6 +1124,7 @@ NextMember:
|
|||||||
NextToken ();
|
NextToken ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EndOfDecl:
|
||||||
if (NeedClean > 0) {
|
if (NeedClean > 0) {
|
||||||
/* Must be followed by a semicolon */
|
/* Must be followed by a semicolon */
|
||||||
if (ConsumeSemi ()) {
|
if (ConsumeSemi ()) {
|
||||||
@ -1181,6 +1199,13 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags)
|
|||||||
DeclSpec Spec;
|
DeclSpec Spec;
|
||||||
int NeedClean = 0;
|
int NeedClean = 0;
|
||||||
|
|
||||||
|
/* Check for extra semicolons */
|
||||||
|
if (CurTok.Tok == TOK_SEMI) {
|
||||||
|
/* TODO: warn on this if we have a pedantic mode */
|
||||||
|
NextToken ();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for a _Static_assert */
|
/* Check for a _Static_assert */
|
||||||
if (CurTok.Tok == TOK_STATIC_ASSERT) {
|
if (CurTok.Tok == TOK_STATIC_ASSERT) {
|
||||||
ParseStaticAssert ();
|
ParseStaticAssert ();
|
||||||
@ -1197,6 +1222,16 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we haven't got a type specifier yet, something must be wrong */
|
||||||
|
if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) {
|
||||||
|
/* Avoid extra errors if it was a failed type specifier */
|
||||||
|
if ((Spec.Flags & DS_EXTRA_TYPE) == 0) {
|
||||||
|
Error ("Declaration specifier expected");
|
||||||
|
}
|
||||||
|
NeedClean = -1;
|
||||||
|
goto EndOfDecl;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allow anonymous bit-fields */
|
/* Allow anonymous bit-fields */
|
||||||
Spec.Flags |= DS_ALLOW_BITFIELD;
|
Spec.Flags |= DS_ALLOW_BITFIELD;
|
||||||
|
|
||||||
@ -1362,6 +1397,7 @@ NextMember:
|
|||||||
NextToken ();
|
NextToken ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EndOfDecl:
|
||||||
if (NeedClean > 0) {
|
if (NeedClean > 0) {
|
||||||
/* Must be followed by a semicolon */
|
/* Must be followed by a semicolon */
|
||||||
if (ConsumeSemi ()) {
|
if (ConsumeSemi ()) {
|
||||||
@ -1559,6 +1595,8 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags)
|
|||||||
|
|
||||||
case TOK_UNION:
|
case TOK_UNION:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
/* Remember we have an extra type decl */
|
||||||
|
Spec->Flags |= DS_EXTRA_TYPE;
|
||||||
/* Check for tag name */
|
/* Check for tag name */
|
||||||
if (CurTok.Tok == TOK_IDENT) {
|
if (CurTok.Tok == TOK_IDENT) {
|
||||||
strcpy (Ident, CurTok.Ident);
|
strcpy (Ident, CurTok.Ident);
|
||||||
@ -1570,8 +1608,6 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags)
|
|||||||
UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE);
|
UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Remember we have an extra type decl */
|
|
||||||
Spec->Flags |= DS_EXTRA_TYPE;
|
|
||||||
/* Declare the union in the current scope */
|
/* Declare the union in the current scope */
|
||||||
TagEntry = ParseUnionSpec (Ident, &Spec->Flags);
|
TagEntry = ParseUnionSpec (Ident, &Spec->Flags);
|
||||||
/* Encode the union entry into the type */
|
/* Encode the union entry into the type */
|
||||||
@ -1582,6 +1618,8 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags)
|
|||||||
|
|
||||||
case TOK_STRUCT:
|
case TOK_STRUCT:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
/* Remember we have an extra type decl */
|
||||||
|
Spec->Flags |= DS_EXTRA_TYPE;
|
||||||
/* Check for tag name */
|
/* Check for tag name */
|
||||||
if (CurTok.Tok == TOK_IDENT) {
|
if (CurTok.Tok == TOK_IDENT) {
|
||||||
strcpy (Ident, CurTok.Ident);
|
strcpy (Ident, CurTok.Ident);
|
||||||
@ -1593,8 +1631,6 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags)
|
|||||||
UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE);
|
UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Remember we have an extra type decl */
|
|
||||||
Spec->Flags |= DS_EXTRA_TYPE;
|
|
||||||
/* Declare the struct in the current scope */
|
/* Declare the struct in the current scope */
|
||||||
TagEntry = ParseStructSpec (Ident, &Spec->Flags);
|
TagEntry = ParseStructSpec (Ident, &Spec->Flags);
|
||||||
/* Encode the struct entry into the type */
|
/* Encode the struct entry into the type */
|
||||||
@ -1605,6 +1641,8 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags)
|
|||||||
|
|
||||||
case TOK_ENUM:
|
case TOK_ENUM:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
/* Remember we have an extra type decl */
|
||||||
|
Spec->Flags |= DS_EXTRA_TYPE;
|
||||||
/* Check for tag name */
|
/* Check for tag name */
|
||||||
if (CurTok.Tok == TOK_IDENT) {
|
if (CurTok.Tok == TOK_IDENT) {
|
||||||
strcpy (Ident, CurTok.Ident);
|
strcpy (Ident, CurTok.Ident);
|
||||||
@ -1616,8 +1654,6 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags)
|
|||||||
UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE);
|
UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Remember we have an extra type decl */
|
|
||||||
Spec->Flags |= DS_EXTRA_TYPE;
|
|
||||||
/* Parse the enum decl */
|
/* Parse the enum decl */
|
||||||
TagEntry = ParseEnumSpec (Ident, &Spec->Flags);
|
TagEntry = ParseEnumSpec (Ident, &Spec->Flags);
|
||||||
/* Encode the enum entry into the type */
|
/* Encode the enum entry into the type */
|
||||||
@ -1658,9 +1694,7 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags)
|
|||||||
** in DeclareLocals. The type code used here doesn't matter as
|
** in DeclareLocals. The type code used here doesn't matter as
|
||||||
** long as it has no qualifiers.
|
** long as it has no qualifiers.
|
||||||
*/
|
*/
|
||||||
Spec->Flags |= DS_DEF_TYPE;
|
UseDefaultType (Spec, TS_DEFAULT_TYPE_INT);
|
||||||
Spec->Type[0].C = T_INT;
|
|
||||||
Spec->Type[1].C = T_END;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
@ -2376,7 +2410,9 @@ void CheckEmptyDecl (const DeclSpec* Spec)
|
|||||||
** warning if not.
|
** warning if not.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if ((Spec->Flags & DS_EXTRA_TYPE) == 0) {
|
if ((Spec->Flags & DS_TYPE_MASK) == DS_NONE) {
|
||||||
|
/* No declaration at all */
|
||||||
|
} else if ((Spec->Flags & DS_EXTRA_TYPE) == 0) {
|
||||||
Warning ("Declaration does not declare anything");
|
Warning ("Declaration does not declare anything");
|
||||||
} else if (IsClassStruct (Spec->Type) &&
|
} else if (IsClassStruct (Spec->Type) &&
|
||||||
!IsIncompleteESUType (Spec->Type) &&
|
!IsIncompleteESUType (Spec->Type) &&
|
||||||
|
@ -588,6 +588,16 @@ void DeclareLocals (void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we haven't got a type specifier yet, something must be wrong */
|
||||||
|
if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) {
|
||||||
|
/* Avoid extra errors if it was a failed type specifier */
|
||||||
|
if ((Spec.Flags & DS_EXTRA_TYPE) == 0) {
|
||||||
|
Error ("Declaration specifier expected");
|
||||||
|
}
|
||||||
|
NeedClean = -1;
|
||||||
|
goto EndOfDecl;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a comma separated variable list */
|
/* Parse a comma separated variable list */
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
@ -616,6 +626,7 @@ void DeclareLocals (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EndOfDecl:
|
||||||
/* Try some smart error recovery */
|
/* Try some smart error recovery */
|
||||||
if (NeedClean < 0) {
|
if (NeedClean < 0) {
|
||||||
SmartErrorSkip (1);
|
SmartErrorSkip (1);
|
||||||
|
Loading…
Reference in New Issue
Block a user