mirror of
https://github.com/cc65/cc65.git
synced 2024-12-26 08:32:00 +00:00
Changed handling of attributes to a more generic form (it's allowed in each
declaration now) and added a new attribute "unused" to flag unused parameters, variables or functions that shouldn't be warned about. git-svn-id: svn://svn.cc65.org/cc65/trunk@4373 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
5a00b38aab
commit
a5a9700d19
@ -1124,6 +1124,7 @@ static void ParseAnsiParamList (FuncDesc* F)
|
||||
|
||||
DeclSpec Spec;
|
||||
Declaration Decl;
|
||||
SymEntry* Sym;
|
||||
|
||||
/* Allow an ellipsis as last parameter */
|
||||
if (CurTok.Tok == TOK_ELLIPSIS) {
|
||||
@ -1165,7 +1166,10 @@ static void ParseAnsiParamList (FuncDesc* F)
|
||||
ParseAttribute (&Decl);
|
||||
|
||||
/* Create a symbol table entry */
|
||||
AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0);
|
||||
Sym = AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0);
|
||||
|
||||
/* Add attributes if we have any */
|
||||
SymUseAttributes (Sym, &Decl);
|
||||
|
||||
/* If the parameter is a struct or union, emit a warning */
|
||||
if (IsClassStruct (Decl.Type)) {
|
||||
@ -1189,21 +1193,11 @@ static void ParseAnsiParamList (FuncDesc* F)
|
||||
* the breaks above bail out without checking.
|
||||
*/
|
||||
ConsumeRParen ();
|
||||
|
||||
/* Check if this is a function definition */
|
||||
if (CurTok.Tok == TOK_LCURLY) {
|
||||
/* Print an error if we have unnamed parameters and cc65 extensions
|
||||
* are disabled.
|
||||
*/
|
||||
if (IS_Get (&Standard) != STD_CC65 && (F->Flags & FD_UNNAMED_PARAMS)) {
|
||||
Error ("Parameter name omitted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static FuncDesc* ParseFuncDecl (Declaration* D)
|
||||
static FuncDesc* ParseFuncDecl (void)
|
||||
/* Parse the argument list of a function. */
|
||||
{
|
||||
unsigned Offs;
|
||||
@ -1241,20 +1235,6 @@ static FuncDesc* ParseFuncDecl (Declaration* D)
|
||||
/* New style function */
|
||||
ParseAnsiParamList (F);
|
||||
|
||||
/* Allow attributes */
|
||||
ParseAttribute (D);
|
||||
|
||||
/* Check if this is a function definition */
|
||||
if (CurTok.Tok == TOK_LCURLY) {
|
||||
/* Print an error if we have unnamed parameters and cc65 extensions
|
||||
* are disabled.
|
||||
*/
|
||||
if (IS_Get (&Standard) != STD_CC65 &&
|
||||
(F->Flags & FD_UNNAMED_PARAMS)) {
|
||||
Error ("Parameter name omitted");
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Old style function */
|
||||
ParseOldStyleParamList (F);
|
||||
@ -1359,7 +1339,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
|
||||
NextToken ();
|
||||
|
||||
/* Parse the function declaration */
|
||||
F = ParseFuncDecl (D);
|
||||
F = ParseFuncDecl ();
|
||||
|
||||
/* We cannot specify fastcall for variadic functions */
|
||||
if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) {
|
||||
@ -1481,6 +1461,9 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
|
||||
D->StorageClass |= SC_FUNC;
|
||||
}
|
||||
|
||||
/* Parse attributes for this declaration */
|
||||
ParseAttribute (D);
|
||||
|
||||
/* Check several things for function or function pointer types */
|
||||
if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) {
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
||||
|
||||
/* Forwards for attribute handlers */
|
||||
static void NoReturnAttr (Declaration* D);
|
||||
static void UnusedAttr (Declaration* D);
|
||||
|
||||
|
||||
|
||||
@ -67,7 +68,9 @@ struct AttrDesc {
|
||||
};
|
||||
static const AttrDesc AttrTable [] = {
|
||||
{ "__noreturn__", NoReturnAttr },
|
||||
{ "__unused__", UnusedAttr },
|
||||
{ "noreturn", NoReturnAttr },
|
||||
{ "unused", UnusedAttr },
|
||||
};
|
||||
|
||||
|
||||
@ -156,7 +159,7 @@ static void AddAttr (Declaration* D, DeclAttr* A)
|
||||
|
||||
|
||||
|
||||
void NoReturnAttr (Declaration* D)
|
||||
static void NoReturnAttr (Declaration* D)
|
||||
/* Parse the "noreturn" attribute */
|
||||
{
|
||||
/* Add the noreturn attribute */
|
||||
@ -165,6 +168,15 @@ void NoReturnAttr (Declaration* D)
|
||||
|
||||
|
||||
|
||||
static void UnusedAttr (Declaration* D)
|
||||
/* Parse the "unused" attribute */
|
||||
{
|
||||
/* Add the noreturn attribute */
|
||||
AddAttr (D, NewDeclAttr (atUnused));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ParseAttribute (Declaration* D)
|
||||
/* Parse an additional __attribute__ modifier */
|
||||
{
|
||||
|
@ -49,10 +49,8 @@ struct Declaration;
|
||||
|
||||
/* Supported attribute types */
|
||||
typedef enum {
|
||||
atNone = -1, /* No attribute */
|
||||
atNoReturn, /* Function does not return */
|
||||
|
||||
atCount /* Number of attributes */
|
||||
atUnused, /* Symbol is unused - don't warn */
|
||||
} DeclAttrType;
|
||||
|
||||
/* An actual attribute description */
|
||||
|
@ -380,17 +380,24 @@ void NewFunc (SymEntry* Func)
|
||||
/* Reenter the lexical level */
|
||||
ReenterFunctionLevel (D);
|
||||
|
||||
/* Check if the function header contains unnamed parameters. These are
|
||||
* only allowed in cc65 mode.
|
||||
*/
|
||||
if ((D->Flags & FD_UNNAMED_PARAMS) != 0 && (IS_Get (&Standard) != STD_CC65)) {
|
||||
Error ("Parameter name omitted");
|
||||
}
|
||||
|
||||
/* Declare two special functions symbols: __fixargs__ and __argsize__.
|
||||
* The latter is different depending on the type of the function (variadic
|
||||
* or not).
|
||||
*/
|
||||
AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
|
||||
if (D->Flags & FD_VARIADIC) {
|
||||
/* Variadic function. The variable must be const. */
|
||||
static const Type T[] = { TYPE(T_UCHAR | T_QUAL_CONST), TYPE(T_END) };
|
||||
AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
|
||||
/* Variadic function. The variable must be const. */
|
||||
static const Type T[] = { TYPE(T_UCHAR | T_QUAL_CONST), TYPE(T_END) };
|
||||
AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
|
||||
} else {
|
||||
/* Non variadic */
|
||||
/* Non variadic */
|
||||
AddConstSym ("__argsize__", type_uchar, SC_DEF | SC_CONST, D->ParamSize);
|
||||
}
|
||||
|
||||
@ -435,13 +442,13 @@ void NewFunc (SymEntry* Func)
|
||||
/* If this is a fastcall function, push the last parameter onto the stack */
|
||||
if (IsQualFastcall (Func->Type) && D->ParamCount > 0) {
|
||||
|
||||
unsigned Flags;
|
||||
unsigned Flags;
|
||||
|
||||
/* Fastcall functions may never have an ellipsis or the compiler is buggy */
|
||||
CHECK ((D->Flags & FD_VARIADIC) == 0);
|
||||
/* Fastcall functions may never have an ellipsis or the compiler is buggy */
|
||||
CHECK ((D->Flags & FD_VARIADIC) == 0);
|
||||
|
||||
/* Generate the push */
|
||||
if (IsTypeFunc (D->LastParam->Type)) {
|
||||
/* Generate the push */
|
||||
if (IsTypeFunc (D->LastParam->Type)) {
|
||||
/* Pointer to function */
|
||||
Flags = CF_PTR;
|
||||
} else {
|
||||
|
@ -162,7 +162,8 @@ static void CheckSymTable (SymTable* Tab)
|
||||
* defined but not used.
|
||||
*/
|
||||
if (((Flags & SC_AUTO) || (Flags & SC_STATIC)) && (Flags & SC_EXTERN) == 0) {
|
||||
if (SymIsDef (Entry) && !SymIsRef (Entry)) {
|
||||
if (SymIsDef (Entry) && !SymIsRef (Entry) &&
|
||||
SymGetAttribute (Entry, atUnused) == 0) {
|
||||
if (Flags & SC_PARAM) {
|
||||
if (IS_Get (&WarnUnusedParam)) {
|
||||
Warning ("Parameter `%s' is never used", Entry->Name);
|
||||
|
Loading…
Reference in New Issue
Block a user