diff --git a/src/cc65/compile.c b/src/cc65/compile.c index f15c5bc54..73380f3df 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -146,7 +146,7 @@ static void Parse (void) comma = 0; while (1) { - Declaration Decl; + Declarator Decl; /* Read the next declaration */ ParseDecl (&Spec, &Decl, DM_NEED_IDENT); diff --git a/src/cc65/declare.c b/src/cc65/declare.c index f3674d711..459ffa103 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -356,8 +356,8 @@ void InitDeclSpec (DeclSpec* D) -static void InitDeclaration (Declaration* D) -/* Initialize the Declaration struct for use */ +static void InitDeclarator (Declarator* D) +/* Initialize the Declarator struct for use */ { D->Ident[0] = '\0'; D->Type[0].C = T_END; @@ -367,7 +367,7 @@ static void InitDeclaration (Declaration* D) -static void NeedTypeSpace (Declaration* D, unsigned Count) +static void NeedTypeSpace (Declarator* D, unsigned Count) /* Check if there is enough space for Count type specifiers within D */ { if (D->Index + Count >= MAXTYPELEN) { @@ -381,8 +381,8 @@ static void NeedTypeSpace (Declaration* D, unsigned Count) -static void AddTypeToDeclaration (Declaration* D, TypeCode T) -/* Add a type specifier to the type of a declaration */ +static void AddTypeCodeToDeclarator (Declarator* D, TypeCode T) +/* Add a type specifier to the type of a declarator */ { NeedTypeSpace (D, 1); D->Type[D->Index++].C = T; @@ -524,8 +524,8 @@ static void CheckArrayElementType (Type* DataType) -static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags, unsigned* DSFlags) -/* Handle an enum, struct or union forward decl */ +static SymEntry* ForwardESU (const char* Name, unsigned Flags, unsigned* DSFlags) +/* Handle an enum, struct or union forward declaration */ { /* Try to find an enum/struct/union with the given name. If there is none, ** insert a forward declaration into the current lexical level. @@ -584,8 +584,8 @@ static const Type* GetEnumeratorType (long Min, unsigned long Max, int Signed) -static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags) -/* Process an enum declaration */ +static SymEntry* ParseEnumSpec (const char* Name, unsigned* DSFlags) +/* Process an enum specifier */ { SymTable* FieldTab; long EnumVal; @@ -602,7 +602,7 @@ static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags) if (CurTok.Tok != TOK_LCURLY) { /* Just a forward definition */ - return ESUForwardDecl (Name, SC_ENUM, DSFlags); + return ForwardESU (Name, SC_ENUM, DSFlags); } /* Add a forward declaration for the enum tag in the current lexical level */ @@ -754,7 +754,7 @@ static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags) -static int ParseFieldWidth (Declaration* D) +static int ParseFieldWidth (Declarator* D) /* Parse an optional field width. Returns -1 if no field width is specified, ** otherwise the width of the field. */ @@ -832,7 +832,7 @@ static unsigned PadWithBitField (unsigned StructSize, unsigned BitOffs) -static unsigned AliasAnonStructFields (const Declaration* D, SymEntry* Anon) +static unsigned AliasAnonStructFields (const Declarator* D, SymEntry* Anon) /* Create alias fields from an anon union/struct in the current lexical level. ** The function returns the count of created aliases. */ @@ -879,8 +879,8 @@ static unsigned AliasAnonStructFields (const Declaration* D, SymEntry* Anon) -static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags) -/* Parse a union declaration. */ +static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) +/* Parse a union specifier */ { unsigned UnionSize; @@ -895,7 +895,7 @@ static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags) if (CurTok.Tok != TOK_LCURLY) { /* Just a forward declaration */ - return ESUForwardDecl (Name, SC_UNION, DSFlags); + return ForwardESU (Name, SC_UNION, DSFlags); } /* Add a forward declaration for the union tag in the current lexical level */ @@ -929,7 +929,7 @@ static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags) /* Read fields with this type */ while (1) { - Declaration Decl; + Declarator Decl; /* Get type and name of the struct field */ ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); @@ -1026,8 +1026,8 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { -static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags) -/* Parse a struct declaration. */ +static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) +/* Parse a struct specifier */ { unsigned StructSize; @@ -1043,7 +1043,7 @@ static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags) if (CurTok.Tok != TOK_LCURLY) { /* Just a forward declaration */ - return ESUForwardDecl (Name, SC_STRUCT, DSFlags); + return ForwardESU (Name, SC_STRUCT, DSFlags); } /* Add a forward declaration for the struct tag in the current lexical level */ @@ -1079,7 +1079,7 @@ static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags) /* Read fields with this type */ while (1) { - Declaration Decl; + Declarator Decl; /* If we had a flexible array member before, no other fields can ** follow. @@ -1418,7 +1418,7 @@ static void ParseTypeSpec (DeclSpec* D, typespec_t TSFlags, int* SignednessSpeci /* Remember we have an extra type decl */ D->Flags |= DS_EXTRA_TYPE; /* Declare the union in the current scope */ - TagEntry = ParseUnionDecl (Ident, &D->Flags); + TagEntry = ParseUnionSpec (Ident, &D->Flags); /* Encode the union entry into the type */ D->Type[0].C = T_UNION; SetESUTagSym (D->Type, TagEntry); @@ -1437,7 +1437,7 @@ static void ParseTypeSpec (DeclSpec* D, typespec_t TSFlags, int* SignednessSpeci /* Remember we have an extra type decl */ D->Flags |= DS_EXTRA_TYPE; /* Declare the struct in the current scope */ - TagEntry = ParseStructDecl (Ident, &D->Flags); + TagEntry = ParseStructSpec (Ident, &D->Flags); /* Encode the struct entry into the type */ D->Type[0].C = T_STRUCT; SetESUTagSym (D->Type, TagEntry); @@ -1453,14 +1453,13 @@ static void ParseTypeSpec (DeclSpec* D, typespec_t TSFlags, int* SignednessSpeci } else { if (CurTok.Tok != TOK_LCURLY) { Error ("Identifier expected"); - } else { - AnonName (Ident, "enum"); } + AnonName (Ident, "enum"); } /* Remember we have an extra type decl */ D->Flags |= DS_EXTRA_TYPE; /* Parse the enum decl */ - TagEntry = ParseEnumDecl (Ident, &D->Flags); + TagEntry = ParseEnumSpec (Ident, &D->Flags); /* Encode the enum entry into the type */ D->Type[0].C |= T_ENUM; SetESUTagSym (D->Type, TagEntry); @@ -1612,7 +1611,7 @@ static void ParseOldStyleParamList (FuncDesc* F) /* Parse a comma separated variable list */ while (1) { - Declaration Decl; + Declarator Decl; /* Read the parameter */ ParseDecl (&Spec, &Decl, DM_NEED_IDENT); @@ -1667,7 +1666,7 @@ static void ParseAnsiParamList (FuncDesc* F) while (CurTok.Tok != TOK_RPAREN) { DeclSpec Spec; - Declaration Decl; + Declarator Decl; SymEntry* Param; /* Allow an ellipsis as last parameter */ @@ -1748,7 +1747,7 @@ static void ParseAnsiParamList (FuncDesc* F) static FuncDesc* ParseFuncDecl (void) -/* Parse the argument list of a function. */ +/* Parse the argument list of a function with the enclosing parentheses */ { SymEntry* Sym; SymEntry* WrappedCall; @@ -1760,6 +1759,9 @@ static FuncDesc* ParseFuncDecl (void) /* Enter a new lexical level */ EnterFunctionLevel (); + /* Skip the opening paren */ + NextToken (); + /* Check for several special parameter lists */ if (CurTok.Tok == TOK_RPAREN) { /* Parameter list is empty (K&R-style) */ @@ -1817,14 +1819,14 @@ static FuncDesc* ParseFuncDecl (void) -static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) -/* Recursively process declarators. Build a type array in reverse order. */ +static void DirectDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) +/* Recursively process direct declarators. Build a type array in reverse order. */ { - /* Read optional function or pointer qualifiers. They modify the - ** identifier or token to the right. For convenience, we allow a calling - ** convention also for pointers here. If it's a pointer-to-function, the - ** qualifier later will be transfered to the function itself. If it's a - ** pointer to something else, it will be flagged as an error. + /* Read optional function or pointer qualifiers that modify the identifier + ** or token to the right. For convenience, we allow a calling convention + ** also for pointers here. If it's a pointer-to-function, the qualifier + ** later will be transfered to the function itself. If it's a pointer to + ** something else, it will be flagged as an error. */ TypeCode Qualifiers = OptionalQualifiers (T_QUAL_NONE, T_QUAL_ADDRSIZE | T_QUAL_CCONV); @@ -1838,16 +1840,16 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) Qualifiers |= OptionalQualifiers (Qualifiers, T_QUAL_CVR); /* Parse the type that the pointer points to */ - Declarator (Spec, D, Mode); + DirectDecl (Spec, D, Mode); /* Add the type */ - AddTypeToDeclaration (D, T_PTR | Qualifiers); + AddTypeCodeToDeclarator (D, T_PTR | Qualifiers); return; } if (CurTok.Tok == TOK_LPAREN) { NextToken (); - Declarator (Spec, D, Mode); + DirectDecl (Spec, D, Mode); ConsumeRParen (); } else { /* Things depend on Mode now: @@ -1867,7 +1869,13 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) NextToken (); } else { if (Mode == DM_NEED_IDENT) { + /* Some fix point tokens that are used for error recovery */ + static const token_t TokenList[] = { TOK_COMMA, TOK_SEMI }; + Error ("Identifier expected"); + + /* Try some smart error recovery */ + SkipTokens (TokenList, sizeof(TokenList) / sizeof(TokenList[0])); } D->Ident[0] = '\0'; } @@ -1876,14 +1884,11 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN) { if (CurTok.Tok == TOK_LPAREN) { - /* Function declaration */ + /* Function declarator */ FuncDesc* F; SymEntry* PrevEntry; - /* Skip the opening paren */ - NextToken (); - - /* Parse the function declaration */ + /* Parse the function declarator */ F = ParseFuncDecl (); /* We cannot specify fastcall for variadic functions */ @@ -1912,7 +1917,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) Qualifiers = T_QUAL_NONE; } else { - /* Array declaration. */ + /* Array declarator */ long Size = UNSPECIFIED; /* We cannot have any qualifiers for an array */ @@ -1976,7 +1981,7 @@ Type* ParseType (Type* T) /* Parse a complete type specification */ { DeclSpec Spec; - Declaration Decl; + Declarator Decl; /* Get a type without a default */ InitDeclSpec (&Spec); @@ -1994,19 +1999,19 @@ Type* ParseType (Type* T) -void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) -/* Parse a variable, type or function declaration */ +void ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) +/* Parse a variable, type or function declarator */ { /* Used to check if we have any errors during parsing this */ unsigned PrevErrorCount = ErrorCount; - /* Initialize the Declaration struct */ - InitDeclaration (D); + /* Initialize the Declarator struct */ + InitDeclarator (D); - /* Get additional declarators and the identifier */ - Declarator (Spec, D, Mode); + /* Get additional derivation of the declarator and the identifier */ + DirectDecl (Spec, D, Mode); - /* Add the base type. */ + /* Add the base type */ NeedTypeSpace (D, TypeLen (Spec->Type) + 1); /* Bounds check */ TypeCopy (D->Type + D->Index, Spec->Type); @@ -2024,7 +2029,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) D->StorageClass |= SC_FUNC; } - /* Parse attributes for this declaration */ + /* Parse attributes for this declarator */ ParseAttribute (D); /* Check several things for function or function pointer types */ diff --git a/src/cc65/declare.h b/src/cc65/declare.h index 474a848a9..ee9e1fc63 100644 --- a/src/cc65/declare.h +++ b/src/cc65/declare.h @@ -86,8 +86,8 @@ struct DeclSpec { }; /* Result of ParseDecl */ -typedef struct Declaration Declaration; -struct Declaration { +typedef struct Declarator Declarator; +struct Declarator { unsigned StorageClass; /* A set of SC_xxx flags */ Type Type[MAXTYPELEN]; /* The type */ ident Ident; /* The identifier, if any*/ @@ -118,8 +118,8 @@ void InitDeclSpec (DeclSpec* D); Type* ParseType (Type* Type); /* Parse a complete type specification */ -void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode); -/* Parse a variable, type or function declaration */ +void ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode); +/* Parse a variable, type or function declarator */ void ParseDeclSpec (DeclSpec* D, typespec_t TSFlags, unsigned DefStorage); /* Parse a declaration specification */ diff --git a/src/cc65/declattr.c b/src/cc65/declattr.c index 37048e69b..eec89552e 100644 --- a/src/cc65/declattr.c +++ b/src/cc65/declattr.c @@ -2,7 +2,7 @@ /* */ /* declattr.c */ /* */ -/* Declaration attributes */ +/* Declarator attributes */ /* */ /* */ /* */ @@ -55,8 +55,8 @@ /* Forwards for attribute handlers */ -static void NoReturnAttr (Declaration* D); -static void UnusedAttr (Declaration* D); +static void NoReturnAttr (Declarator* D); +static void UnusedAttr (Declarator* D); @@ -64,7 +64,7 @@ static void UnusedAttr (Declaration* D); typedef struct AttrDesc AttrDesc; struct AttrDesc { const char Name[15]; - void (*Handler) (Declaration*); + void (*Handler) (Declarator*); }; static const AttrDesc AttrTable [] = { { "__noreturn__", NoReturnAttr }, @@ -141,8 +141,8 @@ static void ErrorSkip (void) -static void AddAttr (Declaration* D, DeclAttr* A) -/* Add an attribute to a declaration */ +static void AddAttr (Declarator* D, DeclAttr* A) +/* Add an attribute to a declarator */ { /* Allocate the list if necessary, the add the attribute */ if (D->Attributes == 0) { @@ -159,7 +159,7 @@ static void AddAttr (Declaration* D, DeclAttr* A) -static void NoReturnAttr (Declaration* D) +static void NoReturnAttr (Declarator* D) /* Parse the "noreturn" attribute */ { /* Add the noreturn attribute */ @@ -168,7 +168,7 @@ static void NoReturnAttr (Declaration* D) -static void UnusedAttr (Declaration* D) +static void UnusedAttr (Declarator* D) /* Parse the "unused" attribute */ { /* Add the noreturn attribute */ @@ -177,7 +177,7 @@ static void UnusedAttr (Declaration* D) -void ParseAttribute (Declaration* D) +void ParseAttribute (Declarator* D) /* Parse an additional __attribute__ modifier */ { /* Do we have an attribute? */ diff --git a/src/cc65/declattr.h b/src/cc65/declattr.h index 63669cee7..930cd71ff 100644 --- a/src/cc65/declattr.h +++ b/src/cc65/declattr.h @@ -2,7 +2,7 @@ /* */ /* declattr.h */ /* */ -/* Declaration attributes */ +/* Declarator attributes */ /* */ /* */ /* */ @@ -45,7 +45,7 @@ /* Forward */ -struct Declaration; +struct Declarator; /* Supported attribute types */ typedef enum { @@ -67,7 +67,7 @@ struct DeclAttr { -void ParseAttribute (struct Declaration* D); +void ParseAttribute (struct Declarator* D); /* Parse an additional __attribute__ modifier */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 3141a4f4f..303a122dc 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1319,7 +1319,7 @@ static void Primary (ExprDesc* E) Error ("Mixed declarations and code are not supported in cc65"); while (CurTok.Tok != TOK_SEMI) { - Declaration Decl; + Declarator Decl; /* Parse one declaration */ ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); diff --git a/src/cc65/initdata.c b/src/cc65/initdata.c index 51e22cc14..049ce7799 100644 --- a/src/cc65/initdata.c +++ b/src/cc65/initdata.c @@ -624,7 +624,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Standard member. We should never have stuff from a ** bit-field left because an anonymous member was added - ** for padding by ParseStructDecl. + ** for padding by ParseStructSpec. */ CHECK (SI.ValBits == 0); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index ce18b6fd7..0d5b12925 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -103,8 +103,8 @@ static void AllocStorage (unsigned DataLabel, void (*UseSeg) (), unsigned Size) -static void ParseRegisterDecl (Declaration* Decl, int Reg) -/* Parse the declaration of a register variable. Reg is the offset of the +static void ParseRegisterDecl (Declarator* Decl, int Reg) +/* Parse the declarator of a register variable. Reg is the offset of the ** variable in the register bank. */ { @@ -192,8 +192,8 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg) -static void ParseAutoDecl (Declaration* Decl) -/* Parse the declaration of an auto variable. */ +static void ParseAutoDecl (Declarator* Decl) +/* Parse the declarator of an auto variable. */ { unsigned Flags; SymEntry* Sym; @@ -403,8 +403,8 @@ static void ParseAutoDecl (Declaration* Decl) -static void ParseStaticDecl (Declaration* Decl) -/* Parse the declaration of a static variable. */ +static void ParseStaticDecl (Declarator* Decl) +/* Parse the declarator of a static variable. */ { unsigned Size; @@ -462,12 +462,12 @@ static void ParseStaticDecl (Declaration* Decl) static void ParseOneDecl (const DeclSpec* Spec) -/* Parse one variable declaration */ +/* Parse one variable declarator. */ { - Declaration Decl; /* Declaration data structure */ + Declarator Decl; /* Declarator data structure */ - /* Read the declaration */ + /* Read the declarator */ ParseDecl (Spec, &Decl, DM_NEED_IDENT); /* Check if there are any non-extern storage classes set for function diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index 115d47e3f..30ebe7dd8 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -230,8 +230,8 @@ const DeclAttr* SymGetAttr (const SymEntry* Sym, DeclAttrType AttrType) -void SymUseAttr (SymEntry* Sym, struct Declaration* D) -/* Use the attributes from the declaration for this symbol */ +void SymUseAttr (SymEntry* Sym, struct Declarator* D) +/* Use the attributes from the declarator for this symbol */ { /* We cannot specify attributes twice */ if ((Sym->Flags & SC_HAVEATTR) != 0) { diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index d973e6586..5ebd30a75 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -298,8 +298,8 @@ INLINE int SymHasAttr (const SymEntry* Sym, DeclAttrType A) # define SymHasAttr(Sym, A) (SymGetAttr (Sym, A) != 0) #endif -void SymUseAttr (SymEntry* Sym, struct Declaration* D); -/* Use the attributes from the declaration for this symbol */ +void SymUseAttr (SymEntry* Sym, struct Declarator* D); +/* Use the attributes from the declarator for this symbol */ void SymSetAsmName (SymEntry* Sym); /* Set the assembler name for an external symbol from the name of the symbol. diff --git a/src/common/attrib.h b/src/common/attrib.h index a16b94a3b..3cdacb9d5 100644 --- a/src/common/attrib.h +++ b/src/common/attrib.h @@ -46,7 +46,7 @@ #ifdef __clang__ # define attribute(a) __attribute__(a) -# define ATTR_UNUSED(x) x +# define ATTR_UNUSED(x) __attribute__((__unused__)) x # define ATTR_NORETURN __attribute__((analyzer_noreturn)) #elif defined(__GNUC__) # define attribute(a) __attribute__(a) diff --git a/test/ref/Makefile b/test/ref/Makefile index 3c275e308..abd3e9bc0 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -11,14 +11,14 @@ ifdef CMD_EXE NULLDEV = nul: MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) - CP=copy + COPY = copy $(subst /,\,$1) $(subst /,\,$2) else S = / EXE = NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 - CP=cp + COPY = cp $1 $2 endif ifdef QUIET @@ -52,7 +52,8 @@ CUSTOMSOURCES = \ # list of sources that produce a compiler error. a .cref files containing the # exact error output is required ERRORSOURCES = \ - custom-reference-error.c + custom-reference-error.c \ + bug1889-missing-identifier.c SOURCES := $(filter-out $(CUSTOMSOURCES) $(ERRORSOURCES),$(wildcard *.c)) @@ -78,7 +79,7 @@ $(ISEQUAL): ../isequal.c | $(WORKDIR) $(WORKDIR)/%.cref: %.cref | $(WORKDIR) $(if $(QUIET),echo ref/$*.cref) - $(CP) $*.cref $@ + $(call COPY,$*.cref,$@) $(WORKDIR)/%.ref: %.c | $(WORKDIR) $(if $(QUIET),echo ref/$*.host) diff --git a/test/ref/bug1889-missing-identifier.c b/test/ref/bug1889-missing-identifier.c new file mode 100644 index 000000000..d9cf4aa52 --- /dev/null +++ b/test/ref/bug1889-missing-identifier.c @@ -0,0 +1,9 @@ +/* bug 1889 - endless errors due to failure in recovery from missing identifier */ + +int enum { a } x; +inline enum { b }; + +int main(void) +{ + return 0; +} diff --git a/test/ref/bug1889-missing-identifier.cref b/test/ref/bug1889-missing-identifier.cref new file mode 100644 index 000000000..cd3f76849 --- /dev/null +++ b/test/ref/bug1889-missing-identifier.cref @@ -0,0 +1,3 @@ +bug1889-missing-identifier.c:3: Error: Identifier expected +bug1889-missing-identifier.c:4: Error: Identifier expected +bug1889-missing-identifier.c:4: Warning: Implicit 'int' is an obsolete feature